Forum: Compiler & IDEs Interrupt niederer Priorität realisierbar?


von Leo B. (luigi)


Lesenswert?

Servus beisammen,

ich rätsle momentan ein einem für mich recht schwierigen Problem herum.
Es geht darum, dass ich möglichst genau im 1ms-Takt einen Sensor über 
ein SSI-Interface auslesen muss. Ich habe schon viel rumprobiert, doch 
leider lässt sich das Hardware-SPI für dieses Interface nicht 
zurechtbiegen.
Nun habe ich in einem 1ms-Interrupt eines Timers ein Software-SSI 
geschrieben, welches natürlich mit einigen delays den Prozessor für ca. 
30µs blockiert. Leider kommt es vor, dass innerhalb dieser 30µs noch 
wichtigere Interrupts verloren gehen.
Ich suche nun also eine Möglichkeit, wie ich mit meinem Timer-Interrupt 
eine Funktion anspringen und durchlaufen kann, ohne andere Interrupts zu 
blockieren?!
Ich schätze ich müsste also manuell den Programmzähler und diverse 
Register sichern und anschließend meinen "Interrupt niedrigerer 
Priorität" ausführen.

Die Frage die ich mir nun nach einer Stunde erfolgloser Internetsuche 
immer noch stelle ist, ob denn das überhaupt in GCC auf einem AVR 
ATmega48 möglich ist?
Kann mir dazu jemand Tips und Hinweise geben?

Vielen Dank
Leo

PS: Die "Interrupts höherer Priorität" sind wirklich nur kleine 
Interrupts und bestehen aus nicht mehr als 3x Register umkopieren und 
einer einfachen Verzweigung.

von Karl H. (kbuchegg)


Lesenswert?

du kannst innerhalb einer ISR mittels sei() die INterruptsperre 
grundsätzlich wieder aufheben.
Register sichern brauchst du nicht, nur musst du dafür sorgen, dass sich 
deine ISR nicht immer weiter ineinander schachteln. WEnn das kein 
Problem ist, weil die ISR Aufrufe seltener kommen, als die ISR 
tatsächlich braucht, dann spricht nichts dagegen.

von --- (Gast)


Lesenswert?

Ich gestehe, dass ich deine Ausführung nicht ganz verstehe. Warum sollte 
die
Die kleinen AVR verfügen nur über feste Interruptprioritäten. Diese ist 
aber nur für gleichzeitig eintretende Interrupts relevant.

Ich vermute, dir geht es um unterbrechbare/geschachtelte 
Interruptroutinen. Dies ist auch bei AVRs kein Problem 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Unterbrechbare_Interruptroutinen

Allerdings muss dein Gesamttiming funktionieren können.
Delays in einem Timerinterrupt klingen für mich absolut unzulässig. 
Überdenke noch einmal dein Design, oder erklär uns deine 
Problemstellung.

von Oliver (Gast)


Lesenswert?

--- schrieb:
> Leider kommt es vor, dass innerhalb dieser 30µs noch
> wichtigere Interrupts verloren gehen.

Du hast Interrupts, die mit 67kHz oder schneller getaktet sind? Das ist 
eh schon sportlich.

Aber egal, du kannst diese Interrupts in deiner 30µs-ISR freigeben. Wenn 
du auf Nummer sicher gehen willst, gibst du nur genau diese schnelle 
Interruptquelle frei. Dann kann dir kein anderer Interrupt das Timing 
kaputtmachen.

Oliver

von Peter D. (peda)


Lesenswert?

Leo B. schrieb:
> Ich habe schon viel rumprobiert, doch
> leider lässt sich das Hardware-SPI für dieses Interface nicht
> zurechtbiegen.

Daß Du es nicht schaffst, ist aber noch lange kein Beweis, daß es 
wirklich nicht geht.
Zeig mal den Link zum Datenblatt des Sensors.


Peter

von Leo B. (luigi)


Lesenswert?

Oliver schrieb:
> Du hast Interrupts, die mit 67kHz oder schneller getaktet sind? Das ist
> eh schon sportlich.

Nein, aber die Abarbeitung einer SPI-Interruptroutine kann halt nicht 
30µs warten. Da taktet der SPI-Master schon ein neues Byte durch und das 
Slave hat sein Schieberegister noch gar nicht gelesen und neu 
beschrieben.


Peter Dannegger schrieb:
> Daß Du es nicht schaffst, ist aber noch lange kein Beweis, daß es
> wirklich nicht geht.
> Zeig mal den Link zum Datenblatt des Sensors.

Gerne doch: 
http://www.austriamicrosystems.com/content/download/1285/7214/file/AS5040_Datasheet_v2_01.pdf
MOSI -> PROG
MISO -> DO
CLK  -> CLK
#SS  -> CSn

Problem ist, dass schonmal ein Clk-Pulse vor den Daten kommen muss, oder 
dass PROG low sein muss beim CSn high->low übergang, da sonst der 
Programmiermodus anläuft und gelesene Daten schrott sind.
Wenn jemand ne lösung hat. Ich freu mich!
Angeschlossen ist der AS5040 übrigens bei mir am USART(ATmega48) im 
MSPI-Modus...

von Peter D. (peda)


Lesenswert?

Leo B. schrieb:
> oder
> dass PROG low sein muss beim CSn high->low übergang

Nö, beim 0->1 Übergang. Und da kann man den Modus so wählen, daß das 
letzte Datenbit anliegt.

Mußt Du überhaupt programmieren?
Wenn nicht, einfach MOSI offen lassen.
Wenn doch, über nen anderen Pin programmieren (SW-SPI).


Peter

von Leo B. (luigi)


Lesenswert?

Peter Dannegger schrieb:
> Nö, beim 0->1 Übergang. Und da kann man den Modus so wählen, daß das
> letzte Datenbit anliegt.

Tatsache, naja jedenfalls kommt Müll aus dem Chip wenn beim 1->0 
Übergang MOSI auf 1 ist. Programmieren muss ich zwar im Moment nicht, 
offen halten möchte ich mir die Option allerdings und die Leiterbahn ist 
halt schon da, durchtrennen will ich sie jetzt nicht unbedingt.

Ich denke ich komme aber fürs erste schon recht gut mit euren 
Vorschlägen klar. Dass man im Interrupt wieder Interrupts freigeben kann 
war mir nicht klar. Danke. Damit werde ich mich bei nächster Gelegenheit 
(morgen oder übermorgen) spielen.

von Peter D. (peda)


Lesenswert?

Du könntest mal probieren, ob Empfang auch geht, wenn man TXEN auf 0 
setzt:

"The disabling of the transmitter or receiver in USART in MSPIM mode is 
identical in function to
the normal USART operation."

Dann sollte ja TXD der IO-Pin PD1 sein und auf 0 setzbar.


Peter

von Leo B. (luigi)


Lesenswert?

Peter Dannegger schrieb:
> Du könntest mal probieren, ob Empfang auch geht, wenn man TXEN auf 0
> setzt: ...

Was auch immer sie mit ihrem Text meinen, sobald RXEN oder TXEN auf 0 
steht geht das gesamte MSPI nicht. Kein Senden von Daten, keine Flags 
werden gesetzt (merkt man wenn sich das Programm aufhängt weil es darauf 
wartet^^). Totenstille im Kasten.

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.