Forum: Mikrocontroller und Digitale Elektronik Bi-Direktionale Kommunikation mit SPI


von Markus (Gast)


Lesenswert?

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

von Falk W. (dl3daz) Benutzerseite


Lesenswert?

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

von Markus (Gast)


Lesenswert?

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.

von Falk W. (dl3daz) Benutzerseite


Lesenswert?

> 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

von Markus (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Dirk (Gast)


Lesenswert?

Hi,

muss vielleicht DORD noch gesetzt werden (MSB/LSB) ?

von Markus (Gast)


Lesenswert?

Nein, MSB kommt zuerst bei dem AS7924. DORD ist auf default (0, MSB
first)

von Markus (Gast)


Lesenswert?

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