Forum: Mikrocontroller und Digitale Elektronik SPI - SPDR Register auslesen


von Loomit (Gast)


Lesenswert?

Hey Leute,

ich arbeite mit dem ADS1298 von TI und einem ATMega128 und die beiden 
kommunizieren über SPI.

Jetzt möchte ich insgesamt 72-Bit bzw. 9 Byte, die der ADS1298 bitweise 
bei jeder steigenden SCLK-Flanke in das SPDR Register des ATMega128 
ausgibt, lesen.

Und zwar möchte ich das so machen, dass ich jeweils 3 Byte in einer 
"signed long" - Variable speichere.

Ich habe vorher noch nicht mit SPI gearbeitet aber die Verbindung und 
Konfiguration habe ich schonmal.

Jetzt habe ich gelesenen, dass man bevor man das SPDR Register lesen 
kann immer ein Dummybyte senden muss, also folgendermaßen:

// SPI: Receive
// ------------
unsigned char SPI_ReceiveByte(unsigned char data)
{
  /* send dummy byte */
  SPDR = data;
  /* wait until transmission done */
  while(!(SPSR & (1<<SPIF)));
  /* get data from SPDR register */
  data = SPDR;
  return data;
}

Ist das richtig?

Um 3 Byte zu lesen und in einer Variable zu speichern müsste ich das 
also so machen:

// SPI: Receive (3Byte)
// --------------------
signed long SPI_Receive_3Byte(void)
{
  unsigned char dummy = 0x00;
  signed long data = 0x00000000;

  SPDR = dummy;
  while(!(SPSR & (1<<SPIF)));
  data = SPDR;
  data << 8;

  SPDR = dummy;
  while(!(SPSR & (1<<SPIF)));
  data = SPDR;
  data << 8;

  SPDR = dummy;
  while(!(SPSR & (1<<SPIF)));
  data = SPDR;

  return data;
}

Viele Grüße

Loomit

von Thomas E. (thomase)


Lesenswert?

Loomit schrieb:
> Jetzt habe ich gelesenen, dass man bevor man das SPDR Register lesen
> kann immer ein Dummybyte senden muss,
Blödsinn.

> data = SPDR;
Damit überschreibst du data jedesmal komplett.
data+= SPDR;

mfg.

von Karl H. (kbuchegg)


Lesenswert?

Loomit schrieb:

> Jetzt habe ich gelesenen, dass man bevor man das SPDR Register lesen
> kann immer ein Dummybyte senden muss, also folgendermaßen:

Im Prinzip: ja, darauf läuft es hinaus.
Du scheinst aber das Prinzip von SPI noch nicht verstanden zu haben.

Der Slave kann von sich aus überhaupt nichts senden.
Das Ganze läuft so ab, dass es 3 Leitungen gibt

         Master                              Slave
                    ---------------------->
                    <----------------------

                    ------ Clock ----------

d.h. da gibt es 1 Datenleitung vom Master zum Slave
1 Datenleitung vom Slave zum Master

Damit eine Übertragun möglich ist (nicht vergessen: Eine Übertragung 
wird IMMER vom Master angeleiert!) muss der Master entsprechende Clock 
Pulse generieren. D.h. der Master legt den Zustand eines Bits auf 
'seine' Datenleitung, der Slave legt den Zustand eines Bits auf 'seine' 
Datenleitung. Dann kommt der Clock-Puls woraufhin der Slave nachsieht 
wie der Zustand seiner eingehenden Leitung ist und der Master nachsieht 
wie der Zustand seiner eingehenden Leitung ist.

In Kurzfassung: Mit jedem Clock-Puls wird jeweils 1 Bit ausgetauscht. 
Und zwar gleichzeitig in beiden Richtungen.

Daher muss der Master, wenn er vom Slave 1 Byte lesen will, selber ein 
Byte schicken, damit der Austauschprozess auf Bitebene in Gang kommt. 
Denn nur er, der Master, darf den Clock-Puls erzeugen. Und das tut er 
nur, wenn er 1 Byte schickt.


> Um 3 Byte zu lesen und in einer Variable zu speichern müsste ich das
> also so machen:
>

oder der Einfachheit halber so
1
signed long SPI_Receive_3Byte(void)
2
{
3
  unsigned long data;
4
5
  data = SPI_ReceiveByte( 0x00 );
6
  data <<= 8;
7
  data |= SPI_ReceiveByte( 0x00 );
8
  data <<= 8;
9
  data |= SPI_ReceiveByte( 0x00 );
10
11
  return data;
12
}

Wozu das Rad neu erfinden? Du hast eine Funktion, die 1 Byte holt. 3 
Bytes holen ist dann einfach nur 3 mal 1 Byte holen.

PS: deine Routine ist fehlerhaft, weil du die Einzelteile nicht 
'zusammensetzt'. Mit

>   data = SPDR;

überschreibst du ja data jeweils komplett neu. Und

>   data << 8;

liefert zwar einen um 8 Bit verschobenen Wert, speichert ihn aber 
nirgends.

von Loomit (Gast)


Lesenswert?

Alles klar, ist einleuchtend!!
Ja bei dem shiften hatte ich was vergessen das stimmt, der speichert das 
nirgends.
Vielen Dank für die Erklärungen!!

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.