Hallo, ich habe mir einen UART mit Interrupts geschrieben der single bytes sendet/empfängt und einen SPI der ganze Strings lesen kann. Problem ist jetzt natürlich, dass mein SPI ewig alles blockiert. Sollte ich mir die Zeit nehmen und meinen SPI mit Interrupts aufbauen? Ich bekomme ja einen Interrupt, wenn die Übertragung komplett ist. Dann wird ja SPIF gesetzt. Aber es wär ja blöd dieses Bit abzufragen. Welche adresse hat dann der Interruptvector? 0x0022? Sorry, falls die fragen zu doof sind.
mager schrieb: > Welche adresse hat dann der Interruptvector? 0x0022? ohne zu wissen um welchen µC es sich handelt wird es schwer hie weiter zu helfen.
Seite 57 im Datenblatt des Atmega64 "0x0022 SPI, STC SPI Serial Transfer Complete" mach ich dann:
1 | #define SPI_INTERRUPT 0x0022
|
2 | |
3 | und dann? |
4 | |
5 | IST(SPI_INTERRUPT) |
mager schrieb: > mach ich dann:#define SPI_INTERRUPT 0x0022 das sollte doch schon alles von jemand gemacht wurden sein. Das braucht man nicht selber zu machen! Das steht in einer der include dateien für den µC mit drin.
Ok, das wäre schön. Aber wo finde ich es und wie füge ich es ein?
Im iom64.h
1 | /* SPI Serial Transfer Complete */
|
2 | #define SPI_STC_vect_num 17
|
3 | #define SPI_STC_vect _VECTOR(17)
|
4 | #define SIG_SPI _VECTOR(17)
|
Es heißt ja "Transfer complete", wird dann die ISR aufgerufen wenn ich ein byte gesendet habe oder wenn ich eines empfangen habe? Oder beides? Im Master Modus lese ich ja mit einem Dummy byte, dann löst er doch den Interrupt auch aus.
mager schrieb: > Perdon.. > >
1 | > ISR(SPI_INTERRUPT) |
2 | > { |
3 | >
|
4 | > } |
5 | >
|
Also wenn das C sein soll, dann überlass es deinem Compiler, sich um den Interruptvektor zu kümmern. Du schreibst nur: ISR(SPI_STC_vect) { } Und gibst die Interrupts frei. > Ok, das wäre schön. > Aber wo finde ich es und wie füge ich es ein? Das wird dir auf einem silbernen Tablett beim Erstellen deines Projektes serviert. Darum brauchst du dich überhaupt nicht zu kümmern. Du solltest alerdings mal das GCC-Tutorial durcharbeiten. Oder was für einen Exoten von Compiler verwendest du? > Es heißt ja "Transfer complete", wird dann die ISR aufgerufen wenn ich > ein byte gesendet habe oder wenn ich eines empfangen habe? Oder beides? Kannst du dir aussuchen. Wenn der Spi-Clock 8 mal gewackelt hat, ist die Übertragung fertig. Dann gibt es einen Interrupt. Senden und Empfangen passiert dabei gleichzeitig. Und Master oder Slave ist auch egal. mfg.
Schau mal in das Datenblatt Deines AVR. Dort steht eine Tabelle mit den Interruptnamen. Leerzeichen ersetzt man durch _ und hinten fügt man ein _vect an, fertig ist der Vector-Name. Und dann noch:
1 | #include <avr/io.h> |
Ok das hab ich jetzt ein für alle mal abgespeichert, danke für die Antworten. Nun zur wichtigsten Frage, ich bin immer Master. Dann bringt mir ja der Interupt eigentlich gar nichts oder?
mager schrieb: > Nun zur wichtigsten Frage, ich bin immer Master. Dann bringt mir ja der > Interupt eigentlich gar nichts oder? Kommt drauf an. Wenn der Spi-Clock F_CPU/2 ist, dauert die Übertragung 16 Takte. Die Ausführung eines Interrupts, das nächste Byte aus dem Buffer holen und ins Spdr schreiben dauert wesentlich länger. Da wartet man dann. Anders sieht es natürlich aus, wenn die Peripherie nur eine wesentlich niedrigere Geschwindigkeit zulässt. Dann willst du bei F_CPU/256 nicht wirklich 4096 Takte auf der Stelle treten. Da macht der Interrupt wieder Sinn. mfg.
Ich hab jetzt schon einiges ausprobiert, weiß aber ehrlich gesagt nicht so recht, was ich in der ISR eigentlich machen soll. Ich würde jetzt nur einen Buffer inkrementieren.
mager schrieb: > Problem ist jetzt natürlich, dass mein SPI ewig alles blockiert. Sicher? Wie hast Du festgestellt, daß genau das der Flaschenhals ist.
Soll ich dann in der ISR ein Flag abfragen, also write und read? und dementsprechend die buffer inkrementieren etc? Gibts dazu evtl ein beispiel? Interrupt driven spi fand ich nichts passendes im web.
mager schrieb: > Soll ich dann in der ISR ein Flag abfragen, also write und read? und > dementsprechend die buffer inkrementieren etc? Was für ein Flag? Beim SPI gibt es doch sowieso nur ein einziges Ereignis. Der Transfer ist fertig. Punkt. Mehr gibt es da nicht. Wenn also der Interrupt kommt, dann weißt du, das das letzte zeichen komplett draussen ist (und im Gegenzug ein Zeichen von der Gegenseite rübergeschoben wurde). Was also wirst du machen? Es gibt 2 Möglichkeiten * entweder gibt es noch was zu transferieren, dann stopfst du das nächste Zeichen ins SPDR Register, damit das ebenfalls transferiert wird * oder es gibt nichts mehr zu tun. IN dem Fall macht dann eben die ISR nichts. Wo ist da jetzt das Problem? > > Gibts dazu evtl ein beispiel? Wie wärs, wenn du mal selber ein wenig nachdenkst, was da eigentlich vor sich geht. Wie das SPI System funktioniert? > Interrupt driven spi fand ich nichts passendes im web. Googeln können ist wichtig. Aber noch wichtiger ist es, sich selbst mal ein bischen was zu überlegen. SPI funktioniert so, wie wenn sich 2 Personen am Tisch gegenüber sitzen. Jeder hat ein Kuvert, in welches er eine Nachricht stecken kann (die nur aus einer einzigen Zahl im Bereich 0 bis 255 besteht). Die eine der Personen ist der Master. Der hat das sagen. Der Master nimmt sein Kuvert in die rechte Hand (genauso wie der Slave). Beide strecken nun ihre rechte Hand aus und schieben das Kuvert über den Tisch zum jeweiligen Gegenüber. Und zwar gleichzeitig. Der Master nimmt mit seiner linken das Kuvert vom Slave und der Slave nimmt mit seiner linken das Kuvert vom Master. Damit ist der Datenaustausch vollzogen. Jeder der beiden (Master und Slave) können jetzt ins Kuvert schauen und nachsehen, was der jeweils andere mitteilt. Aber Auslöser des Ganzen ist immer der Master. Der Slave kann seinen Namen tanzen wenn er will, das hilft nichts. Der Master ist der, der das sagen hat. Er beginnt damit den Kuvertaustausch anzustossen. Jetzt kommen Interrupts ins Spiel. Der Interrupt wird genau dann ausgelöst, wenn das Kuvert komplett ausgetauscht wurde. Kunststück. Was anderes erwähnenswertes gibt es da ja auch nicht. Und das ist jetzt der Punkt, an dem die Ehefrau ins Spiel kommt (das Hauptprogramm in Form der ISR). Sobald der Master das Kuvert hat, läutet eine Glocke, die Ehefrau tritt hinzu und macht, was immer sie für richtig hält. Sie kann sich ansehen was im Kuvert stand, sie kann dem Master auftragen, dass er was neues ins Kuvert schreiben und rüberschieben soll, sie kann aber auch nichts dergleichen tun. Je nachdem. Zack: Das ist im wesentlichen SPI. Mehr ist da nicht. Es gibt kein dezidiertes 'Senden' oder 'Empfangen'. Die beiden SPI Teilnehmer tauschen Bytes aus, wobei der Master der ist, der alles anstösst und taktet. Und aus dieser Basisfunktionalität musst du jetzt eben was machen, so das du die Funktionalität kriegst, die du brauchst. Der grundlegende Transfermechanismus ist da, alles weitere ist jetzt dein Bier.
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.