mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik SPI0 als Slave mit ARM7 LPC2148


Autor: Geri (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen

Ich versuche gerade am LPC2148 die SPI0 als Slave zu codieren.

Der Sender sendet Daten an den Slave (beide Boards mit LP2148).

Der Datenempfang funktioniert über eine Interruptroutine einwandfrei. 
Versuche ich hingegen Daten an den Master zurück zu senden, dann sendet 
der Slave mehr oder weniger Schrott. Das sehe ich, wenn ich den Ausgang 
MISO am Oszi, getriggert mit SEL0 anlege.

Das Senden funktioniert auch in der ISR. Zuvor wird der Sendepuffer
durch den Aufruf von SPI0WriteBuf(...) initialisiert. Das findet 
unmittelbar nach dem Detenempfang statt.

unsigned char SPI0_tx_buffer[50];
unsigned char SPI0_tx_len;
unsigned char SPI0_tx_Idx;

void SPI0WriteBuf(unsigned char* buf, unsigned char size)
{
    unsigned char i;
    unsigned char crc=0;
    
    memcpy(&SPI0_tx_buffer[0],buf,size);
    for (i=0; i< size; i++)
    {
        crc = crc8_Table[crc ^ SPI0_tx_buffer[i+3]];
    }
    SPI_tx_buffer[size] = crc;
    SPI0_tx_len = size + 1;
    SPI0_tx_len--;
    SPI0_tx_Idx++;  
    S0SPDR = SPI0_tx_buffer[0]; // fülle Puffer mit erstem Element
}

static void SPI0_Isr(void)
{
  static uint8_t NewData;
  static uint16_t Idx = 0;
  static uint8_t Mode = 0;
    
   if ((S0SPSR & 0x70) !=0)         // check status register for error
  {                                
    NewData = S0SPSR;
  }
  else
   if (Mode == 0x01)   // check if slave in send mode
  {
    NewData = S0SPDR;  

    if (SPI0_tx_len > 0)
    {
      SPI0_tx_len--;
      S0SPDR = SPI0_tx_buffer[SPI0_tx_Idx++];      
    }
    else
    {
      Mode = 0x00; // switch slaave to receive mode
    }
  }
  else
  {
    NewData = S0SPDR;   // read data received    
    // snip,  Verarbeitung empfanger Daten
    
  }
  S0SPINT  = 0x01;               // reset interrupt flag
  VICVectAddr = 0;               // reset VIC
}


Habt ihr vielleicht ein Idee

Vielen Dank für Eure Anregungen

Geri

Autor: Geri (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm, vielleicht liegt es dran..

http://www.standardics.nxp.com/support/documents/m...

Der Slave ist mit   S0SPCR   = 0x80; initialisiert (CPOL = 0; CHPA=0);

SCR beim Master = 0x20; // ca. 100 KHz

Autor: Ralph (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du wirst nie in den Sendepfad deiner ISR routine gelangen.
Zu Beginn der ISR initialisierst du Mode mit "0".
Da Mode danach niemals auf 0x01 gesetzt wird, ergibt sich daraus, das du 
bei der IF abfrage IMMER in den ELSE Pfad springst.
Sollte Mode extern geändert werden, dann muss Mode eine Globale und 
keine Locale Variable sein, und zudem mit dem Zusatz "volatile".

Der Slave sendet somit das was gerade im hardwarebuffer der SPI steht, 
und nicht das was du im SPI0_tx_buffer stehen hast.

Autor: Geri (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Ralph

Vielen Dank für Deine Rückmeldung!

Ich habe in der ISR einen Teil herausgenommen. Gekennzeichnet mit

" // snip,  Verarbeitung empfanger Daten "

Sorry für die Konfusion, dieses Flag hätte ich im Thread nicht 
herausnehmen sollen.

In dieser Emfangsroutine wir nach erfolgreichem Empfang Mode auf 0x01 
gesetzt. Die ISR springt dann auch in den Sendeteil rein, das habe ich 
geprüft. Ich habe nach Angaben des Erata sheet dann noch verschiedene 
Konfigurationen mit CHPA =1 und höheren Taktraten versucht, allerdings 
erfolglos.

In der Zwischenzeit habe ich den Code nach SPI1 portiert und siehe da, 
die Kommunikation funktioniert einwandfrei. SPI1 ist dazu noch 
leistungsfähiger.

SPI0 als Slave würde ich nach meinem aktuellem Wissenstand niemand 
empfehlen. Vielleicht kann mir aber noch jemand das Gegenteil beweisen:)

Beste Grüsse

Geri

Autor: Geri (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Ich bin nun auf die SSP umgestiegen

Master (LPC2148) und Slave (LPC2148)


Das Senden von Daten vom Master zum Slave funktioniert einwandfrei. 
Möchte ich jedoch Daten vom Slave empfangen, dann wird - soweit ich es 
aktuell sehe - das erste Datenbyte vom Master mehrmals gelesen.


Die Receive-Routine beim Master sieht so aus:
unsigned char SpiReceiveByte( void )
{
  unsigned char incoming;

         while( !(SSPSR & (1<<TNF)) ) ;
  SSPDR = 0xFF;   /* wrtie dummy byte out to generate clock, then read data from MISO */ 
  while( !(SSPSR & (1<<RNE)) ) ;
  incoming = SSPDR;
  return(incoming);
}


Die Sende-Routine beim Slave sieht so aus:
unsigned char SpiSendByte(unsigned char outgoing)
{
  unsigned char incoming;
  
  while( !(SSPSR & (1<<TNF)) ) ; // wait until at least one byte if free in Fifo-Buffer
  SSPDR = outgoing;
  while( !(SSPSR & (1<<RNE)) ) ; // receive buf not empty
  incoming = SSPDR;
  return(incoming);
}


Beide Schnittstellen sind mit fClk = 333333 Hz initialisiert. CPOL = 0;

Hat jemand vielleicht eine Idee woran es liegen könnte

Vielen Dank und beste Grüsse

Geri

Autor: Geri (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch eine Zusatzinfo. Soviel ich hier mit dem Oszi messen kann, sendet 
der Slave die richtigen Daten. Ich denke, es liegt demnach beim Master.

Autor: Geri (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Ich komme hier aber einfach nicht weiter.

Gibt es ausser dem Datenblatt von NXP eigentlich ein anderes brauchbares 
Dokument in dem die Programmierung der SPI1 erklärt wird?

Vielen Dank für einen Tipp

Geri

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.