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