www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik SPI bidirektional 32 Bit AVR


Autor: Gary Gru (gary)
Datum:

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

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>gibts ein C-Beispiel für Slave- Send?

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

Autor: Gary Gru (gary)
Datum:

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

Autor: Gary Gru (gary)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Anhang?

Autor: inoffizieller WM-Rahul (Gast)
Datum:

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

Autor: Gary Gru (gary)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
du meinst

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

aufrufen bevor ich das Dataregister fülle?

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja

Autor: Gary Gru (gary)
Datum:

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

Autor: Gary (Gast)
Datum:

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

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.