Hallo Zusammen, ich kämpfe mal wieder mit der SPI-Schnittstelle. Mein Ziel ist es, zwei MCU miteinander zu verbinden. Einer läuft als Master, einer als Slave. Beim Master läuft soweit alles gut. Nur beim Slave gibt es merkwürdige Probleme: Zur Fehleranalyse lasse ich immer eine LED aufleuchten und verschiebe diese Routine zum aufleuchten lassen immer im Code umher, bis ich die kritische Stelle gefunden habe. Es scheint, als würde sich der µC immer am Ende der SPI_SlaveInit() aufhängen. Das seltsame ist jedoch, dass wenn ich die Testroutine am Ende von SPI_SlaveInit() ansetze, die LED aufleuchtet, doch wenn ich sie im MAIN-Code direkt hinter dem Aufruf von SPI_SlaveInit() ansetze, die LED eben nicht aufleuchtet. Klingt irgendwie nach nem Interrupt der ausgelöst wird und den µC zum Reset zwingt, aber Interrupts hab ich nicht aktiviert. Hoffe ihr könnt mir weiterhelfen. LG Lukas
Lukas S. schrieb: > doch wenn ich sie > im MAIN-Code direkt hinter dem Aufruf von SPI_SlaveInit() ansetze, die > LED eben nicht aufleuchtet. Ich sehe in Deinem Code keine Anweisung zum Anschalten einer LED, d.h. keine Anweisung, irgendeinen Portpin auf "High" zu schalten. Das hier:
1 | DDRA|=1<<2; |
setzt lediglich den Portpin PA2 auf Ausgang. Das Kommando um diesen auf "High" zu schalten lautet:
1 | PORTA |= (1<<PA2); |
J.-u. G. schrieb: > Ich sehe in Deinem Code keine Anweisung zum Anschalten einer LED, d.h. > keine Anweisung, irgendeinen Portpin auf "High" zu schalten. Die LEDs sind so geschaltet, dass sie genau dann leuchten, wenn ihr PIN auf Low ist. Da alle PINS nach einem PowerUp auf Low sind, kann ich mir folgende Codesequenz sparen.
1 | PORTA&=~_BV(PA2); |
Lukas S. schrieb: > Es scheint, als würde sich der µC immer am Ende der SPI_SlaveInit() > aufhängen. Das seltsame ist jedoch, dass wenn ich die Testroutine am > Ende von SPI_SlaveInit() ansetze, die LED aufleuchtet, doch wenn ich sie > im MAIN-Code direkt hinter dem Aufruf von SPI_SlaveInit() ansetze, die > LED eben nicht aufleuchtet. M103C Fuse noch aktiv?
Hmm, auf gesetztes SPIF testen und nur wenn gesetzt die Flaglöschensequenz ausführen ?
Stefan Ernst schrieb: > M103C Fuse noch aktiv? Wieder was gelernt. Jip war noch aktiv. Danke MWS schrieb: > Hmm, auf gesetztes SPIF testen und nur wenn gesetzt die > Flaglöschensequenz ausführen ? hab das mal folgendermaßen umgesetzt:
1 | void SPI_SlaveInit() |
2 | {
|
3 | // set MISO output, all other input
|
4 | DDR_SPI=(1<<DD_MISO); |
5 | // enable SPI
|
6 | SPCR=(1<<SPE); |
7 | // clear SPI Interrupt Flag by reading SPSR and SPDR
|
8 | if (SPSR&(1<<SPIF)) |
9 | {
|
10 | uint8_t c=SPSR; |
11 | c=SPDR; |
12 | DDRA|=1<<2; |
13 | }
|
14 | }
|
Aber nach erfolgter Übertragung sollte ja das SPIF gesetzt werden... scheint aber nicht zu erfolgen... Bin ja jetzt nach Deaktivieren des M103C paar Steps weiter.. jetzt hängt es hier:
1 | uint8_t SPI_SlaveReceive(void) |
2 | {
|
3 | // wait for reception complete
|
4 | while (!(SPSR&(1<<SPIF))) |
5 | ;
|
6 | return SPDR; |
7 | }
|
also beim pollen. Die Übertragung findet aber sinngemäß statt, hab das mit nem LogicAnalyzer überprüft... Habt ihr ne Idee wo hier das Problem sein könnte? Danke schonmal!
Lukas S. schrieb: > void SPI_SlaveInit() > { > // set MISO output, all other input > DDR_SPI=(1<<DD_MISO); > // enable SPI > SPCR=(1<<SPE); > // clear SPI Interrupt Flag by reading SPSR and SPDR > if (SPSR&(1<<SPIF)) > { > uint8_t c=SPSR; > c=SPDR; > DDRA|=1<<2; > } > }[/c] > > Aber nach erfolgter Übertragung sollte ja das SPIF gesetzt werden... > scheint aber nicht zu erfolgen... Du sagst es. Aber nach der Initialisierung wurde ja noch nichts übertragen. Daher ist in diesem Fall das SPIF nicht gesetzt. (Ja ich weiß. Man kommt leicht in Versuchung das SPIF Bit als eine Art: die SPI ist jetzt frei und benutzbar anzusehen. Nur stimmt diese Sicht leider nicht. Nachdem SPI eingeschaltet wurde, ist sie frei und benutzbar, aber trotzdem ist SPIF nicht gesetzt. Das wird dann erst nach der ersten Übertragung gesetzt.
Karl Heinz Buchegger schrieb: > Du sagst es. > Aber nach der Initialisierung wurde ja noch nichts übertragen. Die Daten kommen von einer anderen MCU, welche mit der auskommentierten Codesequenz aus der Main-Routine bespielt ist. Die Übertragung funktioniert nach Vorschrift.
Hallo, ich habe meine zwei Atmega128 auch über SPI verbunden. SPSR = 0x00; //Status-Register einfach beim Init einmal überschreiben ! void SPI_SlaveInit(void) { DDRB |= (1 << SPI_MISO) ; //MISO Ausgang SPCR = (1 << SPE) ; // Slave enable SPSR = 0x00; // Status-Register einfach einmal überschreiben !!!! } dann sollte es funktionieren.
Danke für die Antwort, ich habs ausprobiert und es zeigt sich leider keine Veränderung. Hab im Anhang mal nen Bild vom LogicAnalyzer. Das Programm des Slaves fragt ab, ob eine 0x73 gesendet wurde und soll dann eigentlich eine LED aufleuchten lassen. Im Bild sieht man, dass der Ringspeicher bereits die 0x73 erfolgreich eingelesen hat, nachdem ich den Befehl mehrmals übermittelt habe. Doch besteht weiterhin das Problem, dass SPIF nicht gesetzt wird und ich somit aus dem Pollen nicht rauskomme und im SPI_SlaveReceive() hängenbleibe... =/ Hab bereits die MCU ausgetauscht(M103C Fuse deaktiviert), aber das hat auch keine Veränderung hervorgerufen...
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.