Von SPI mit Polling zu SPI mit ISR

Gast #2860581
Lesenswert?

Hallo zusammen,

habe Schwierigkeiten SPI mit Interrupt zu schreiben und brauche 
unbedingt Hilfe.

Ich habe folgende Funktion mit Polling und weiß nicht wie ich es 
umschreiben muss um eine ISR zu verwenden.


ISR(SPI_STC_vect){
}

void SPI_MasterWrite(uint8_t Adress, uint8_t Daten)
{
  PORTB &= ~(1<<PB1);

  SPDR = Adresse  ;
  while(!(SPSR & (1<<SPIF)))
    ;
  SPDR = Daten ;
  while(!(SPSR & (1<<SPIF)))
    ;
  PORTB |= (1<<PB1);

}
#2860605
Lesenswert?

@spi Anfänger (Gast)

>Ich habe folgende Funktion mit Polling und weiß nicht wie ich es
>umschreiben muss um eine ISR zu verwenden.

SPI mit Interrupt loht sich nur, wenn man wirklich SPI eher langsam 
betreiben muss, weil die ICs das so brauchen. Ansonsten fährt man SPI 
mit maximal möglicher Geschwindigkeit mit Polling. ISt schneller und 
einfacher.

>ISR(SPI_STC_vect){
>}

Hier springt deine CPU rein, wen eine SPI-Übertragung beendet wurde. Was 
macht man dann?

1.) Die gelesenen Daten speichern, SPDR auslesen
2.) Neue Daten, soweit vorhanden, in SPDR schreiben.
3.) Wenn keine neuen Daten mehr zu schreiben/lesen sind, CS inaktiv 
schalten.
Gast #2860647
Lesenswert?

Hatte im Netz ein Beispiel gefunden mit globaler Variable damit die ISR 
sie auch kennt.

Bekomme es aber einfach nicht hin das auf meins umzuschreiben.




uint8_t globalDaten;


void SPI_MasterInit(void)
{
  uint8_t sreg = SREG;

  DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK)|(1<<DD_SS);        //Set MOSI and 
SCK output, all others input

//Interrupts kurz deaktivieren
  cli();

  SPCR = (1<<SPIE)|(1<<SPE)|(1<<MSTR);

  //Global Interrupt flag wieder herstellen
  SREG = sreg;
}



void SPI_MasterWrite(uint8_t Adresse, uint8_t Daten)
{
  PORTB &= ~(1<<PB1);

  if((SPSR & (1<<SPIF)) >0 )
  SPDR = Adresse  ;        // Start transmission of adress

  if((SPSR & (1<<SPIF)) >0 )
  SPDR = Daten ;          // Start transmission of data (register)

 PORTB |= (1<<PB1);
}


ISR(SPI_STC_vect)
{
  SPDR = globalDaten;
}
#2860651
Lesenswert?

@  spi Anfänger (Gast)

>Hatte im Netz ein Beispiel gefunden mit globaler Variable damit die ISR
>sie auch kennt.

Mit EINEM einzigen Byte ist SPI und Interrupt reichlich sinnlos. Wenn, 
dann muss man ganze Arrays übertragen. Wie das ungefähr geht, sieht man 
hier.

http://www.mikrocontroller.net/articles/Interrupt#UART_mit_Interrupts

Muss man halt für SPI umschreiben. Dazu braucht es u.a. einen Zähler, 
wieviele Bytes noch übertragen werden sollen.

Das ist eine Aufgabe för den Schöler.
Moderator Persönliche Seite #2860653
Lesenswert?

Geh nochmal zurück auf "Los!".  Denk drüber nach, warum du
überhaupt SPI mit Interrupt haben willst.  Solange du nichts hast,
was du parallel zum SPI-Transfer abarbeiten kannst, wird die Sache
nur langsamer: das Reinspringen in die ISR benötigt bereits
hardwareseitig genauso lange wie eine Poll-Schleife auf SPIF, dann
kommt aber noch der Prolog und Epilog des Compilers für die ISR
dazu.

Solange du nur versuchst, einen Interrupt zu benutzen, nur weil man das
überhaupt so tun könnte, aber am Ende der main thread nur drauf
wartet, bis die ISR fertig ist, ist das alles ziemlicher Humbug.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren