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); }
@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.
Könntest du das bitte anhand meines Beispiels mal codieren? Bei mir hat es irgendwie noch nicht Klick gemacht.
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; }
@ 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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.