Forum: Mikrocontroller und Digitale Elektronik SPI bidirektional 32 Bit AVR


von Gary G. (gary)


Lesenswert?

Guten Tag,

Hat einer Ehrfahrung mit 32-Bit Wörtern und SPI? Ich muss zwischen zwei 
Mikrocontrollern Pakete von X*32 Bit übertragen. Als Master senden und 
auf die Antwort vom Slave warten.
Momentan stückele ich das Wort zusammen indem ich erst nach den 4x8-Bit 
eine steigende Flanke am SS Pin erzeuge, sprich solange den SS Pin Lo 
halte.
Das ganze kommt auch gut an beim Slave, spätestens beim zweiten Wort 
wird LSByte und MSByte vertauscht. Sobald ich die Daten allerdings nicht 
vom Slave zurück zum Master sende klappts. Und wenn ich die

while!(SPSR & (1<<SPIF));

Abfrage nicht mache gehts auch. Frage ist brauch ich diese while-Zeile 
in der
Slave Sender funktion?

Entschuldigung für den Roman aber ich weiss langsam nicht mehr weiter. 
gibts ein C-Beispiel für Slave- Send?

von inoffizieller WM-Rahul (Gast)


Lesenswert?

>gibts ein C-Beispiel für Slave- Send?

Poste lieber deinen Code.
Ansonsten steht sowas auch gerne im Datenblatt beschrieben...

von Gary G. (gary)


Lesenswert?

Ein Beispiel für sendenden Slave hab ich im Datenblatt nicht gefunden. 
ich poste mal ein Stück Code wo ich den fehler vermute. im Anhang 
nochmal TX und RX komplett.


void SPI_Slave_Tx(unsigned long wert)
{
  SPDR = (unsigned char) (wert>>24);  //load register Hi-Byte

  while(!(SPSR & (1<<SPIF)));    //wait till TXready

  SPDR = (unsigned char) (wert>>16);

  while(!(SPSR & (1<<SPIF)));

  SPDR = (unsigned char) (wert>>8);

  while(!(SPSR & (1<<SPIF)));

  SPDR = (unsigned char) (wert);    //load register Lo-Byte

  while(!(SPSR & (1<<SPIF)));    //wait till TXready
},

wenn jemand nen fehler findet bitte schreiben.
danke gary

von Gary G. (gary)


Angehängte Dateien:

Lesenswert?

Anhang?

von inoffizieller WM-Rahul (Gast)


Lesenswert?

Du solltest erst abfragen, ob "TX ready" ist und dann die Daten 
"loswerfen".

von Gary G. (gary)


Lesenswert?

du meinst

while(!(SPSR & (1<<SPIF)));

aufrufen bevor ich das Dataregister fülle?

von inoffizieller WM-Rahul (Gast)


Lesenswert?

ja

von Gary G. (gary)


Lesenswert?

ja danke Rahul, ich werds gleich morgen mal ausprobieren (hab das zeug 
nicht zu hause) und dann berichten

von Gary (Gast)


Lesenswert?

hmm, ja jetzt kommst an und wird auch korrekt rausgeschickt aber nur 
wenn ich erst slave und dann master resete, sonst kommt er gern mit 
MSByte und LSByte durcheinander.
Das nächste Problem ist jetzt aber: wenn ich die 32 Bit am Master 
empfangen will macht er nicht weiter. mit 8-Bit klappt alles prima ich 
muss aber leider ein 32-Bit wort senden. vielleicht habe ich da was 
grundlegend falsch gemacht also wenn da jemand was sieht...
Danke Gary


//Main Loop:
for(;;)
{
  test_data++;

        SPI_Mstr_Tx(test_data);

  loop_back = SPI_Mstr_Rx();
}

// Master TX und RX
void SPI_Mstr_init(void)
{        //MOSI, SCK, SS und Enable = Output
  DDRB = (1<<DDB0)|(1<<DDB1)|(1<<DDB2)|(1<<DDB4);
  //PORTB = (1<<PB6); // pullups??
  SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);
}

//SPI transceive
void SPI_Mstr_Tx(unsigned long wert)
{
  unsigned char Lo;
  unsigned char LM;
  unsigned char HM;
  unsigned char Hi;

  PORTB &= ~(1<<PB4);    //Enable = 0

  Hi = (unsigned char) (wert>>24);
  SPDR = Hi;

  while(!(SPSR & (1<<SPIF)));  //wait till TXready

  HM = (unsigned char) (wert>>16);
  SPDR = HM;

  while(!(SPSR & (1<<SPIF)))

  LM = (unsigned char)(wert>>8);
  SPDR = LM;

  while(!(SPSR & (1<<SPIF)));

  Lo = (unsigned char)(wert);
  SPDR = Lo;      //load register Lo-Byte

  while(!(SPSR & (1<<SPIF)));  //wait till TXready

  PORTB |= (1<<PB4);    //steigende Flanke => enable

        //Debug Ausgaben
  #if DEBUG == 2
  deb(Hi,0,0);
  deb(HM,5,0);
  deb(LM,10,0);
  deb(Lo,15,0);
  #endif

}

//SPI Master Receive
unsigned long SPI_Mstr_Rx(void)
{
  PORTB &= ~(1<<PB4);    //Enable = 0
  unsigned long word;
  unsigned char Lo;
  unsigned char LM;
  unsigned char HM;
  unsigned char Hi;

//  SPDR = 0xff;

  while(!(SPSR & (1<<SPIF)));

  Hi = SPDR;

  word = Hi;
  word <<= 8;

  while(!(SPSR & (1<<SPIF)));

  HM = SPDR;
  word += HM;
  word <<= 8;

  while(!(SPSR & (1<<SPIF)));

  LM = SPDR;
  word += LM;
  word <<= 8;

  while(!(SPSR & (1<<SPIF)));

  Lo = SPDR;
  word += Lo;

        //Debug Ausgaben
  #if DEBUG == 2
  deb(Hi,0,1);
  deb(HM,5,1);
  deb(LM,10,1);
  deb(Lo,15,1);
  #endif

  PORTB |= (1<<PB4);  //steigende Flanke => enable
  return word;
}

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.