mikrocontroller.net

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


Autor: Johann (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Johann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Über die SPI-Schnittstelle wird immer zuerst das MSB übertragen.

Autor: Frederik Krämer (n0ll4k)
Datum:

Bewertung
0 lesenswert
nicht 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.
uint16_t eins;
uint16_t zwei;


uint8_t u2 = (uint8_t)(zwei)

eins << 2;
zwei >> 8;

eins |= (zwei & 0x000F);

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

Dann müsstest du deine 3 Bytes nur noch richtig schicken.

Autor: Büroinventar (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!?
uint32 soll_kanal1;
uint32 soll_kanal2;

uint8 soll_both[3];

soll_both[0] = (uint8)soll_kanal1;
soll_both[1] = (uint8)(soll_kanal1<<8);
soll_both[1] &= 0xF0;
soll_both[1] |= (uint8)(soll_kanal2>>4);
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]

Autor: Johann (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

siehe Seite 5

Autor: Johann (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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;

}

Autor: Frederik Krämer (n0ll4k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wofür die unsigned int typecast.

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

Autor: Johann (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Johann (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Frederik Krämer (n0ll4k)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Johann (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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"

Autor: Frederik Krämer (n0ll4k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmt hab mich vertan. Schiebs auf aus der Mittagspause kommen ;)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.
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] & 0x0FFF;   // sicher ist sicher
   dac_2 = ptr_datenpuffer[2] & 0x0FFF;

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

Autor: Johann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für den Hinweis.

Autor: Johann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und vor allem für die verinfachte Darstellung.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.