Forum: Mikrocontroller und Digitale Elektronik 2x16Bit zu 1x14Bit wandeln


von Johann (Gast)


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.

von Johann (Gast)


Lesenswert?

Über die SPI-Schnittstelle wird immer zuerst das MSB übertragen.

von Frederik K. (n0ll4k)


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.

von Büroinventar (Gast)


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]

von Johann (Gast)


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

von Johann (Gast)


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;

}

von Frederik K. (n0ll4k)


Lesenswert?

wofür die unsigned int typecast.

achja mit [ c ] [ / c ] (ohne leerzeichen) kannst du auch c-code 
darstellen lassen.

von Johann (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


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.

von Johann (Gast)


Lesenswert?

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?

von Frederik K. (n0ll4k)


Lesenswert?

Das Hin und hershiften von deinem ersten Byte ist eher nicht so der 
Renner. Da gehen dir ja die ersten Bytes quasi bei verloren.

von Johann (Gast)


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"

von Frederik K. (n0ll4k)


Lesenswert?

Stimmt hab mich vertan. Schiebs auf aus der Mittagspause kommen ;)

von Karl H. (kbuchegg)


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
}

von Johann (Gast)


Lesenswert?

Danke für den Hinweis.

von Johann (Gast)


Lesenswert?

Und vor allem für die verinfachte Darstellung.

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
Noch kein Account? Hier anmelden.