Forum: Mikrocontroller und Digitale Elektronik SPI Bidirektional


von Jonas (Gast)


Lesenswert?

Hallo zusammen

Ich habe SPI soweit programmiert, dass ich mit untenstehender Routine 
ein Byte an den Slave schicken kann.:

char SPI_MasterTransmit(char cData)
{
  uint8_t rc;

  PORTB &= ~(1<<0);  //SS low
  // Start transmission
  SPDR = cData;

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

  // Wait for transmission complete
  PORTB |= (1<<0);  //SS high

  return (SPDR);
}

Nun weiss ich, dass ich mit folgedem Codestück ein Byte auf dem Slave 
empfangen kann, wenn SPI_SlaveReceive() ausgeführt wurde.

char SPI_SlaveReceive(void)
{
  /* Wait for reception complete */
  while (!(SPSR) & (1<<SPIF));

  return SPDR;
}

Nun möchte ich, dass der Slave gleichzeitig beim Empfang auch ein 
Zeichen an den Master zurückschick (also ein Byte exchange), was mit SPI 
ja möglich sein sollte. Muss ich dass Zeichen nun unmittelbar nach dem 
Empfang auf den Bus legen oder muss dies vor dem Empfang schon 
passieren?

Vielen Dank.

von Falk B. (falk)


Lesenswert?

@ Jonas (Gast)

>Ich habe SPI soweit programmiert, dass ich mit untenstehender Routine
>ein Byte an den Slave schicken kann.:

Und das geht auch wirklich? Deine Kommentare verwirren ein wenig. 
Ausserdem liest du SPDR doppelt, das is unnötig und kann ggf. ins Auge 
gehen. Eher so.
1
char SPI_MasterTransmit(char cData)
2
{
3
  uint8_t rc;
4
5
  PORTB &= ~(1<<0);  //SS low
6
  
7
  SPDR = cData;            // Start transmission
8
9
  while(!(SPSR & (1 << SPIF)));    // Wait for transmission complete
10
  rc = SPDR;
11
  PORTB |= (1<<0);  //SS high
12
13
  return rc;
14
}

>Nun weiss ich, dass ich mit folgedem Codestück ein Byte auf dem Slave
>empfangen kann, wenn SPI_SlaveReceive() ausgeführt wurde.

Nöö, das ist eine Illusion. Du müsstes ja erstmal die Übertragung 
starten.

>Nun möchte ich, dass der Slave gleichzeitig beim Empfang auch ein
>Zeichen an den Master zurückschick (also ein Byte exchange), was mit SPI
>ja möglich sein sollte.

Ja. Das macht dein Routine oben schon. Was glaubst du, was in rc steht?

> Muss ich dass Zeichen nun unmittelbar nach dem
>Empfang auf den Bus legen oder muss dies vor dem Empfang schon
>passieren?

Wer soll was wan auf welchen Bus legen?

MFG
Falk

von Jonas (Gast)


Lesenswert?

Hallo Falk

Das mit dem doppelten Auslesen von SPDR war ein Copy-Paste-Fehler das 
ist natürlich richtig wie du korrigiert hast.

Richtig in rc, steht das Zeichen, welcher der Salve auf den Bus gelegt 
hat. Meine Frage war nur wann und wie muss der Slave das Zeichen auf den 
Bus legen?  In der Slave-Routine wo ich angegeben habe wird nur ein 
Zeichen empfangen, nicht aber gesendet.

von Falk B. (falk)


Lesenswert?

@ Jonas (Gast)

>Meine Frage war nur wann und wie muss der Slave das Zeichen auf den
>Bus legen?

In dem Zyklus, nachdem SS auf LOW gegangen ist.

MFG
Falk

von Jonas (Gast)


Lesenswert?

Also so:

char SPI_SlaveReceive(char cData)
{
  SPDR=cData;

  /* Wait for reception complete */
  while (!(SPSR) & (1<<SPIF));

  return SPDR;
}

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.