Forum: Mikrocontroller und Digitale Elektronik Senderoutine mit Interrupts & Busy


von Benedikt (Gast)


Lesenswert?

Zwei AVRs tauschen Daten über SPI aus.
Damit das ganze auch mit hohen Datenraten läuft, gibt der Slave ein
Busy aus, da dieser eventuell mit länger dauernden Berechnungen
beschäftigt ist, und somit keine Zeit hat sich mit dem Master zu
unterhalten.

Die Datenausgabe des Master läuft über Interrupts. Ich habe dazu einen
Sendepuffer, den ich fülle und der dann im Hintergrund an den Slave
übertragen wird.
Soweit läuft das ganze problemlos.

Jetzt habe ich aber das Busy Signal. Der Master fragt dieses also ab,
und wartet bis Busy weg ist ehe er Daten sendet. Daher kann es
vorkommen, dass der Master mehrere ms im Interrupt hängen bleibt, wenn
der Slave beschäftigt ist.

Leider habe ich keine Idee, wie man das geschickt lösen könnte.

von Hannes L. (hannes)


Lesenswert?

In der ISR (SPI fertig) nur ein Flag für die Mainloop setzen?

Das Senden des nächsten Bytes übernimmt dann die Mainloop bei gesetztem
Flag, vorhandenem nächsten Byte (Ringbufferpointer) und gültigem Busy.
Das Flag löscht die Mainloop nur, wenn sie ein neues Byte gesendet
hat.

So würde diese Routine auch selbsttätig erkennen, wenn neue Bytes zur
Übertragung im Ringbuffer anstehen/eintreffen.

...

von Mathias (Gast)


Lesenswert?

Hallo Benedikt,

ich würde das ganze so lösen:

Im Interrupthandler des Slaves wird nur das empfangene Byte in den
Buffer geschrieben und ein Flag gesetzt, dass ein neues Byte empfangen
wurde. In deiner Main Loop fragst du dann das Flag ab und verarbeitest
das empfangene Byte. Bei einem erneuten Senden vom Master unterbricht
der Interrupt einfach das Hauptprogramm. Somit sparst du dir dein Busy
Flag und kannst einfach drauf los senden. Ein Problem bekommst du erst
wenn der Buffer voll ist (würde einen Ringbuffer verwenden, der so groß
ist, dass sichergestellt ist dass der Slave die empfangenen Daten
schnell genug verarbeiten kann). Du kannst dir ja damit helfen, wenn du
die Übertragungsgeschwindigkeit möglichst langsam machst (CLK/128)!
Somit hat der Slave mehr Zeit zum rechnen.

Mfg, Mathias

von Peter Dannegger (Gast)


Lesenswert?

Jedesmal, wenn der Slave ein Byte abgeholt bzw. eins ins Senderegister
gestellt hat, macht er auf dem Busy einen 0-1-0 Impuls. Der löst dann
beim Master einen externen Interrupt aus und der kann dann das nächste
Byte takten.

D.h. die SPI-Lese/Schreibroutine wird im externen oder SPI Interrupt
ausgeführt, wer eben als letzter kommt.


Peter

von Mathias (Gast)


Lesenswert?

@ peter: bei der spi übertragung werden doch die datenreg. des master
und slaves ausgetauscht oder? wenn ich also die mosi des slaves an die
miso des masters hänge muss ich doch nur nach beendigung der
übertragung  überprüfen ob im datenreg. tatsächlich das gesendete bye
ist..

ein problem hab ich halt dann wenn ich 2x hintereinander das selbe byte
sende oder?

mfg, mathias

von Benedikt (Gast)


Lesenswert?

@Mathias
die Idee mit dem Ringpuffer geht nicht, da ich nebenher noch vieles
andere mache, und der Slave nicht gestört werden darf (er muss etwas
Hardware ansteuern und da ist das Timing kritisch).
fclk/128 scheitet aus, ist einfach viel zu langsam.

@Peter
Die externe Interrupt Routinen Idee ist echt gut.
Ich denke ich werde es so machen.

von Peter Dannegger (Gast)


Lesenswert?

Es geht noch einfacher:

externer Interrupt:
- SPI-Interrupt enablen

SPI-Interrupt:
- SPI-Interrupt disablen
- Byte senden

Ist quasi ne UND-Verknüpfung beider Interrupts


Peter

von Hannes L. (hannes)


Lesenswert?

Oder gleich Master und Slave vertauschen?

von Peter D. (peda)


Lesenswert?

@HanneS

???

Einer muß Slave und einer Master sein.

Und der Master muß irgendwie mitbekommen, wann der Slave das Byte
abgeholt bzw. eins reingestellt hat.

Oder der Master macht riesige Wartezeiten nach jedem Byte.

Tja, wenn das SPI eine FIFO hätte, hats aber nicht.


Peter

von Hannes L. (hannes)


Lesenswert?

@Peter:

Ich meinte damit (scherzhaft), dass der höher belastete AVR als Master
geschaltet werden sollte und die Übertragung managt. Damit bestimmt er,
wann das nächste Byte geholt wird. Das geht natürlich nur, wenn keine
weiteren Geräte am SPI-Bus hängen.

Wobei das jetzt nicht zu Ende gedacht ist, denn über die SS-Leitung
kann ja auch ein Multimastersystem erreicht werden. Wenn ich das
richtig verstanden habe, kann jeder Teilnehmer, der "sich zum Master
erklärt", über die SS-Leitung alle anderen Teilnehmer "zu Slaves
degradieren" (sofern es AVRs sind).

Aber die Idee mit dem Ack-Impuls via ext.-Interrupt ist schon nicht
schlecht.

Ja, Fifo für SPI und UART wäre schon eine echte Bereicherung. Aber man
kann leider nicht alles haben.

Bit- & Bytebruch...
...HanneS...

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
Noch kein Account? Hier anmelden.