www.mikrocontroller.net

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


Autor: Markus (Gast)
Datum:

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

Autor: Falk Willberg (dl3daz) Benutzerseite
Datum:

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

Autor: Markus (Gast)
Datum:

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

Autor: Falk Willberg (dl3daz) Benutzerseite
Datum:

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

Autor: Markus (Gast)
Datum:
Angehängte Dateien:

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

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

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

Autor: Markus (Gast)
Datum:

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

Autor: Markus (Gast)
Datum:

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

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.