Hallo zusammen, ich bin dabei, einen 12Bit ADC (Typ AD7924) über den SPI eines ATMEGA32 zu realisieren und scheitere gerade an der SPI Kommunikation,bzw. an dem Verständis für Selbiges. Zunächst eine Generelle Frage zum SPI. Muss der ATMEGA32 im Slave Modus sein, um Daten zu empfangen? Die Verbindung sieht folgendermaßen aus: ATMEGA32 AD7924 SCLCK----->SCLCK MOSI------>DIN MISO------>DOUT !SS-------->!CS Laut Datenblatt wird der SS im Master-Mode nicht benutzt und dient daher dem ChipSelect. Was ich nicht verstehe, ist dass es nur ein Datenregister gibt für das MEGA32 SPI. Die Ansteuerung des AD7924 geschieht über ein UINT16. Also in der Art //Initialisiere ControlBits uint16_t ADC_CtrlReg=ADC_WRITE<<1|ADC_ADD1<<0|ADC_ADD0<<0|ADC_PM1<<1|ADC_PM0<<1|A DC_CODING<<1; lbyte=ADC_CtrlReg; hbyte=ADC_CtrlReg>>8; SPI_CS(0); //setzte CS aktive low //sende high byte SPDR = hbyte; loop_until_bit_is_set(SPSR,SPIF); //sende high byte SPDR = lbyte; loop_until_bit_is_set(SPSR,SPIF); SPI_CS(1); //CS auf low Laut Datenplatt des AD7924 wird zeitgleich das Ergebnis der letzten Konvertierung über DOUT geschickt (ebenfalls 16Bit). Wie kann ich diese Daten auslesen, wenn ich im selben Moment Daten sende und das gleiche Register verwende? Danke im Voraus für eure Hilfe. /Markus
Hallo. Ich bin zwar nicht der große Experte, habe SPI erst kürzlich genutzt. > Muss der ATMEGA32 im Slave Modus sein, um Daten zu empfangen? Nein. Der Master gibt den Takt an, der Slave wird getaktet. Das ist IMO der wichtigste Unterschied. > ATMEGA32 AD7924 > SCLCK----->SCLCK > MOSI------>DIN "Master Out Slave In", dann muß der AVR Master sein. > MISO------>DOUT > !SS-------->!CS > Was ich nicht verstehe, ist dass es nur ein Datenregister gibt für > das MEGA32 SPI. Ich stelle mir Master und Slave immer als 2 8bit Schieberegister vor. Der Master taktet, Ausgang des einen ist mit dem Eingang des jeweils anderen SR verbunden (MISO/MOSI). Ich schreibe ein Byte ins SR (SPDR), nach 8 Takten steht das beim Partner im SR und das, was er ins SR geschrieben hat, in meinem SR (SPDR). > Die Ansteuerung des AD7924 geschieht über ein > UINT16. Also in der Art > ADC_WRITE<<1|ADC_ADD1<<0|ADC_ADD0<<0|... Das sieht ganz schlecht aus. Warum schiebst Du den Wert mal um 0, mal um 1 Bit? Meintest Du nicht vielleicht "(1<<ADC_WRITE)|(0<<ADC_ADD1)"? Irgendwas | (0<<DATUM) macht zwar exakt nichts, verbessert aber die Lesbarkeit des Codes. ... > SPDR = hbyte; Jetzt wird Dein erstes Byte übertragen, den Wert aus dem ADC kannst Du danach aus dem SPDR lesen. (Wenn er was geschickt hat) ... Bis ich es verstanden hatte, erschien mir SPI richtig kompliziert. Dabei ist es so einfach... Hoffe, geholfen zu haben, Falk
ADC_WRITE<<1|ADC_ADD1<<0|ADC_ADD0<<0|... Das sieht ganz schlecht aus. Warum schiebst Du den Wert mal um 0, mal um 1 Bit? Meintest Du nicht vielleicht "(1<<ADC_WRITE)|(0<<ADC_ADD1)"? Genau das meinte ich ;-) Ich hab den ADC bisher so angesteuert. SPI_CS(0); WRITE_BYTE(hbyte); WRITE_BYTE(lbyte); SPI_CS(1); SPI_CS(0); READ_BYTE(hbyte_result); READ_BYTE(lbyte_result); SPI_CS(1); Dabei kam bisher nur Mist raus. Ich denke, so könnte es funktionieren???: SPI_CS(0); hresult=write_BYTE(hbyte); lresult=write_BYTE(lbyte); SPI_CS(1); //////////////////////////////////////// uint8_t SPI_Write(uint8_t value) { SPDR = value; loop_until_bit_is_set(SPSR,SPIF); return SPDR; } /////////////////////////////////////// und das dann jeweils für low und high byte des uint16? Ich werds morgen mal ausprobieren.
> Ich denke, so könnte es funktionieren???: > SPI_CS(0); > hresult=write_BYTE(hbyte); > lresult=write_BYTE(lbyte); > SPI_CS(1); > uint8_t SPI_Write(uint8_t value){ > SPDR = value; > loop_until_bit_is_set(SPSR,SPIF); > return SPDR; } Ohne es ausprobiert zu haben: Das sieht besser aus. Was Dein ADC mit CS und so haben will, weiß ich aber nicht... 73, Falk
Klappt immer noch nicht wirklich. Zum scheint es ein Problem zu sein, dass der AD7924 abzustürzen zu scheint, da er auch mit an MISO/MOSI/SCLCK des ISP hängt. Nun aber zum Phänomen. Es kommen zwar Daten an, diese ergeben jedoch keinen Sinn und stehen in keiner Relation zum analogen Eingangswert. Habe schon verschiedene SCLCK Zeiten Probiert. Der Mega32 läuft mit 8Mhz internem Quartz. Die SCLCK des Mega32 als Master ist auf idle-high gesetzt (scheint aber bei den Daten die vom AD7924 kommen keinen unterschied zu machen). Ich habe mal die relevanten Dateien angehangen. Laut meinem verständis sollte die schaltung laufen, tuts aber nicht.
Nein, MSB kommt zuerst bei dem AS7924. DORD ist auf default (0, MSB first)
Hab das Problem dann doch noch gelöst. Der Fehler lag in der Übertragung des Control Wortes. Ich hatte den UINT16 in 2 Bytes zerlegt und dann rübergeschickt. Nun hatte ich vorne 4 Nullen, dann kam das eigentliche Controlwort. Das war falsch, denn das MSB des ersten Bytes musste gesetzt sein (write option). Also ein <<4 auf das Controlwort, dann in high und lowbyte packen und los gehts mit der 12bit AD Wandlung. Gruß Markus
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.