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.
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.
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]
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
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; }
wofür die unsigned int typecast. achja mit [ c ] [ / c ] (ohne leerzeichen) kannst du auch c-code darstellen lassen.
Genau nach
hatte ich gesucht ^^ Ich hatte so die Erfahrung gemacht das man da ein Typecast einfügen muss. Damit der Compiler weiß welches Bit er schieben soll.
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.
Ich weiß auch das es unsinnig ist einen unsigned int Typecast von einem unsigned int zu machen. Ich werde es mal ohne den Typecast ausprobieren. Was sagst Du denn zu meiner Datenumwandlung?
Das Hin und hershiften von deinem ersten Byte ist eher nicht so der Renner. Da gehen dir ja die ersten Bytes quasi bei verloren.
// 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"
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 | }
|
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.