2x16Bit zu 1x14Bit wandeln

Gast #1841282
Lesenswert?

Hallo @ all

Ich bekomme über eine RS232 Schnittstelle 4 Bytes. Aus den 4 Bytes 
erstelle ich ein 2 Integer Werte. Diese 2 Integerwerte möchte ich über 
eine SPI-Verbindunge an einen DAC senden. Der Digitalanalogwandler 
besitzt eine 24Bit Register, so das dort 2x12Bit reinpassen. Der DAC 
erzeugt aus den 2x12Bit zwei analoge Signale.

Nun ist mein Problem wie kann ich aus den 2 Integerwerten (32Bit) genau 
24Bit erzuegen. Denn ich muss ja 3 mal 8Bit über SPI an den AD-Wandler 
übertragen.
#1841319
Lesenswert?

Ich geh mal davon aus das dein erster uint16 die ersten 12bit enthält 
und der zweite die zweiten..

Dann ist das ganze nur noch rumschieben und maskieren.
1
uint16_t eins;
2
uint16_t zwei;
3

4

5
uint8_t u2 = (uint8_t)(zwei)
6

7
eins << 2;
8
zwei >> 8;
9

10
eins |= (zwei & 0x000F);
11

12
uint8_t u1 = (uint8_t)(eins);
13
uint8_t u0 = (uint8_t)(eins >> 8);

Dann müsstest du deine 3 Bytes nur noch richtig schicken.
Gast #1841336
Lesenswert?

etwas mehr details zum DAC wären gut...
geh ich richtig in der Annahme, das sozusagen aus 4 bytes 2 integert32 
Werte gebildet werden sollen, die wiederrum die Werte für die 2 DAC 
Kanäle darstellen und auf 12bit gerundet werden!?
1
uint32 soll_kanal1;
2
uint32 soll_kanal2;
3

4
uint8 soll_both[3];
5

6
soll_both[0] = (uint8)soll_kanal1;
7
soll_both[1] = (uint8)(soll_kanal1<<8);
8
soll_both[1] &= 0xF0;
9
soll_both[1] |= (uint8)(soll_kanal2>>4);
10
soll_both[2] = (uint8)(soll_kanal2<<8);

dann hast du in soll_both 3x8bit Werte mit

[kanal_1_high][kanal_1_low,kanal_2_high][kanal_2_low]
Gast #1841359
Lesenswert?

Ich habe 2x INT_16 (jeder INT_16 enthält die 12 Bit für den AD-Wandler 
Bit 0 bis Bit 11 sind die wichtigen -->Bit 12 bis Bit 15 sind immer 0)

An den AD-Wandler übertrage ich je 3 Bytes in folgender Reihenfolge

1. Byte DAC 1 (Bit 11 bis Bit 4)
2. Byte DAC 1 (Bit 3 bis Bit 0) und DAC 2 (Bit 11 bis Bit 8)
3. Byte DAC 2 (Bit 7 bis Bit 0)

ich verwende den folgenden Wandler

http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1155,C1005,C1156,P1217,D3168

siehe Seite 5
Gast #1841409
Lesenswert?

Ich habe es jetzt so gelöst. Muss es jedoch noch testen. Vielen Dank für 
die Hinweise:


void dac_1_und dac_2_ansteuern(unsigned int *ptr_datenpuffer)
{
   unsigned char byte_1, byte_2, byte_3;
   unsigned int dac_1, dac_2

   dac_1 = ptr_datenpuffer[1];
   dac_2 = ptr_datenpuffer[2];

   // 1. Byte = DAC 1 Bit (11 bis 4)
   byte_1 = ((unsigned char) (((unsigned int)(dac_1)) >> 4 ));

   // 2. Byte = DAC 1 (Bit 3 bis 0) und DAC 2 (Bit 11 bis 8)
   // Zuerst DAC 1 (Bit 3 bis 0) in Byte 2 schreiben
   byte_2 = ((unsigned char) (((unsigned int)(dac_1)) << 4 ));
   byte_2 |= ((unsigned char) (((unsigned int)(dac_2)) >> 8 ));

   // 3.Byte DAC 2 (Bit 7 bis 0)
   byte_3 = (unsigned char) dac_2;

}
#1841561
Lesenswert?

Johann schrieb:
> Genau nach
 hatte ich gesucht ^^
>
> Ich hatte so die Erfahrung gemacht das man da ein Typecast einfügen
> muss.

Du stimmst aber schon zu, dass es relativ unsinnig ist einen unsigned 
int nach unsigned int zu casten?

> Damit der Compiler weiß welches Bit er schieben soll.

Das weiß er auch so. Steht doch dort wie oft du schieben willst.
Gast #1841642
Lesenswert?

// 1. Byte = DAC 1 Bit (11 bis 4)
   byte_1 = ((unsigned char) (((unsigned int)(dac_1)) >> 4 ));


Hiermit speicher ich in Byte 1 Bit 11 bis 4 vom DAC 1. Der Wert der in 
DAC 1 steht wird dabei nicht verändert, da ich die Manipulation vom DAC 
1 NICHT im DAC 1 speicher.

Der Mikrocontroller lädt ins Alu Register die 2 Bytes aus dem SRAM 
schiebt das ganze um 4 Stellen und speichert es im SRAM in der Variablen 
"byte_1"
#1841657
Lesenswert?

Johann schrieb:
> Ich weiß auch das es unsinnig ist einen unsigned int Typecast von einem
> unsigned int zu machen.

Warum machst du es dann?

> Ich werde es mal ohne den Typecast ausprobieren.

Du brauchst keinen einzigen deiner Casts.

Lediglich wenn dich der Compiler warnt, dass du einen unsigned int an 
einen unsigned char zuweist und da daher Bits verloren gehen werden 
(manche Compiler machen so eine Warnung), ist der Cast des jeweiligen 
rechten Ausdrucks nach unsigned char angebracht.

Aber ansonsten: 'Man castet niemals ohne wirklich triftigen Grund. Jeder 
Cast der nach dem Motto "Ooch, da caste ich jetzt einfach mal" eingefügt 
wird, ist ein böser Cast.

> Was sagst Du denn zu meiner Datenumwandlung?

Was soll ich dazu sagen?
Bitschieben und neu zusammensetzen.

Kommt in abgewandelter Form in anderem Zusammenhang jeden 2.te Tag hier 
im Forum vor.
1
void dac_1_und dac_2_ansteuern(unsigned int *ptr_datenpuffer)
2
{
3
   unsigned char byte_1, byte_2, byte_3;
4
   unsigned int dac_1, dac_2
5

6
   dac_1 = ptr_datenpuffer[1] & 0x0FFF;   // sicher ist sicher
7
   dac_2 = ptr_datenpuffer[2] & 0x0FFF;
8

9
   byte_1 = dac_1 >> 4;                          // von DAC 1: Nibbles 2 + 1
10
   byte_2 = ( dac_1 << 4 ) | ( dac_2 >> 8 );     // von DAC 1: Nibble 0; von DAC 2: Nibble 2
11
   byte_3 = dac_2;                               // von DAC 2: Nibble 1 + 0
12
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren