Schönen guten Morgen zusammen, wollte meine Frage vom 20.12.2006 16:25 nochmal verkürzt formulieren. Würde gerne den ADC mit höchster Priorität durch den AIC "triggern", während "im Hintergrund" kontinuierlich Nebensächliche Programmschritte ablaufen. Häng irgendwie total fest. Was könnte ich denn Dummes vergessen haben oder falsch gemacht haben, bin leider blutiger Anfänger bzgl. µC? Welche grundsätzliche Ablauf ist bei Interrupts wichtig? Vielen, vielen Dank auf jedenfall schon mal für eure Mühen, euer Max
Max wrote: > bin leider blutiger Anfänger > bzgl. µC? Dann hätte ich nicht gleich mit nem 32Bit-Boliden mit tausendenden Seiten Datasheet, Usermanual, Core- und Peripheriebeschreibung angefangen. Man wird sprichwörtlich erschlagen damit. Und das Erlernen des effektiven Programmierens wird stark erschwert. Allgemein sollte man erstmal den Core-Typ, das konkrete Derivat, den Compiler, die IDE nennen, denn Gedanken lesen ist anstrengend. Ich weiß ja nicht, wie schnell der Interrupt ist, aber darin ne Divison auf ner CPU ohne Divisionsbefehl ist Ober-bäh. Peter
Sorry, bei meinem ersten Eintrag hatte ich ein paar mehr Infos angefügt. Ist das Olimexboard SAM7-H64 mit dem AT91SAM7S64 von Atmel. Ich verwende den WinARM und Dev-C++ als Umgebung. Leider MUSS ich mit dem 32bit-er arbeiten, ist ne Studienarbeit :-/ Hab mich schon intensiv mit dem Verhalten befasst, komm auch gut voran, nur eben mit diesem Interruptbereich bin ich mit meinem Latein seit en paar Tagen am Ende. Die Modulo-Division wär nicht wirklich nötig, könnte ja einfach langsamer Interrupten und dann direkt die Fkt. aufrufen, oder? Mit IRH_Entry und ...Exit kannst du mir nicht zufällig weiterhelfen? VG Max
Also generell kann ich wenig helfen (habe diesen uC nie benutzt) aber: (1) check mal deine Syntax - der Begriff "NACKEDFUNC" sollte bestimmt "NAKEDFUNC" heißen (2) google mal nach "at91sam7 examples interrupt download". Gleich der erste Eintrag ist super (3) In solchen Fällen erstmal Interrupts weglassen, dann das Ganze mit Polling zum laufen bringen, dann mit Polling aber gesetzter "Signal-/Statusvariable" im Interrupt und dann mit komplettem Interrupt / hoffe geholfen zu haben
Danke schon mal für die Antworten, wie funktioniert denn das Polling einer Fkt. genau? ... dann mit Polling aber gesetzter "Signal-/Statusvariable" im Interrupt? was ist damit denn genau gemeint? VG Max
du setzt im interrupt nur eine variable, die dann anzeigt, daß ein interrupt aufgetreten ist (z.b. ereignis = 1) wobei die variable global und volatile ist z.b.: volatile uint8_t ereignis; in der hauptschleife wartest du dann, und reagierst, sobald sich die variable ändert: while(1) { while(ereignis != 1); // warte auf ereignis == 1 ereignis = 0; // variable zurücksetzen meine_aktion(); // nun das tun, was später der INT macht }
Hab das Bsp. jetzt mal nachgebaut und in meinen Programmablauf integriert. Leider stehe ich nach wie vor vor dem gleichen Problem. Sobald der Interrupt aktiviert wird, geht gar nichts mehr, sprich ich käme gar nicht in die oben vorgeschlagene while(1)-Schleife :-/ Hab jetzt den ganzen Nachmittag auch mit dem Interrupt-Beispiel von dieser Seite gespielt, dieses ist zwar anders aufgebaut ( Triggert mittels TC ), aber immer noch das gleiche Problem. Die auskommentierte Zeile hab ich in der main-Schleife unmittelbar vor meiner while(1)-Schleife eingefügt. Hab mal meine aktuelle Version angefügt?! Mit bitte um weitere Ratschläge, Max
- ich kann keine main() entdecke - ereignis muß global sein (ist momentan lokal) - ereignis wird nirgends gepollt
Je nach Controller und Compiler kann es erforderlich sein, ein Interrupt-Flag nach dessen Abarbeitung händisch zu löschen. Vielleicht müsste das noch rein.
Hallo zusammen, hallo Philipp, herzlichen Dank für die Nachrichten. Die main () hab ich schon integriert, aber nicht dem Code.txt beigefügt. Hab aber jetzt auch das noch mit angefügt (Neuer-Code.txt), da lösche ich doch das Interrupt-flag "ereignis" händisch, oder? Kann es auch ein Timing- oder Taktproblem sein? Mein Problem ist, dass der ARM WEDER die Interruptroutine NOCH die main-Schleife weiter ausführt, sondern schlichtweg hängen bleibt, bzw. nur noch interruptet?! Ich hoffe auf weitere gute Ideen von euch, VG euer Max
Habs jetzt zum Ausschluss von Fehlern/Defekten der Hardware auf ein Eval-Board gespielt. da läufts komplett gleich ab. Das Verhalten ist folgendes: Die Main-Schleife läuft an, zunächst Initialisierungen etc. (LED1 blinkt!). Dann kommt unmittelbar vor der while(1)-Schleife noch der AIC-Enable. Die Interruptfkt. wird genau ein Mal angestossen (LED2 blinkt genau ein Mal!!!). Dannach würde in der while(1)-Schleife die LED1 blinken, das passiert allerdings nicht mehr. Warum stößt der Interrupt nur EIN MAL die Fkt. an und hängt dannach alles andere auf?????? Ich hoffe sehnlichst auf einen heißen Tipp ;-) VG Max
Könnte es nicht sein, dass ISR_ENTRY() das absolut unbedingt erste codeerzeugende Statement einer ISR sein muss?
Warum eigentlich NAKEDFUNC/ISR_ENTRY statt des dafür vorgesehenen __attribute__((interrupt("IRQ")))? Letzteres hatte zwar früher einen Bug, sollte heute aber ok sein.
Hab mit den Fkt. ISR_ENTRY und ISR_EXIT auch schon herumprobiert. Das einzige, was sich verändert, ist dass er jetzt nicht mal mehr bis an die Stelle LED2 kommt, solange ISR_ENTRY() davor steht ??? Was ist denn genau mit __attribute__((interrupt("IRQ"))) gemeint?
Aber das ändert doch eigentlich nichts an dem prinzipiellen Problem, dass er nur einmal in die durch den Interrupt aufgerufene Fkt. geht und in dieser lediglich den ersten Befehl (LED2 Ein-Aus) abarbeitet, obwohl nachfolgend lediglich dieser Befehl wiederholt wird?
Code der ausgeführt wird, bevor die Register gesichert werden, richtet Schaden an.
Und an welcher Stelle werden genau die Register gesichert? Ist doch noch im Bereich der AIC-Initialisierung, oder? Mich wundert, dass die Fkt. nicht mal zu Ende gearbeitet wird, die der Interrupt aufruft. Zumindest müsste dass aber doch bei jedem neuen Interrupt bis zu der Stelle ständig wiederholt laufen?! Verhalten: LED1 blinkt 4 mal ( Inits OK?! ), danach nur EIN EINZIGES MAL KURZ LED2 ( Interrupt kommt nur einmal und hängt dann? ) Das momentane Code-Bsp. hab ich nochmal angefügt!
Um mal Peter zu zitieren: "Dann hätte ich nicht gleich mit nem 32Bit-Boliden mit tausendenden Seiten Datasheet, Usermanual, Core- und Peripheriebeschreibung angefangen." Dir fehlen elementare Grundlagen der Interrupt-Programmierung, entsprechend betreibst du dabei Blindflug. Es ist sehr hilfreich, wenn man mal Interrupts in Assembler programmiert hat. Dann erschliesst sich einem der Sinn von dem ganzen Zirkus mit __attribute__((interrupt("IRQ"))), __attribute__((naked)), ISR_ENTRY() usw nämlich erst so richtig. Nur sollte man damit nicht grad beim ARMs beginnen. Eine Interrupt-Routine muss alle benutzten Register vor Verwendung sichern. Entweder indem die Routine als solche gekennzeichnet wird __attribute__((interrupt("IRQ"))) oder indem man dem Compiler sagt, dass man alles selber macht __attribute__((naked)) aka NAKEDFUNC und das dann mit ISR_ENTRY/EXIT auch an der richtigen Stelle macht. Sehr hilfreich kann es dabei sein, den entstehenden Assembler-Code zu verstehen.
Danke dennoch für deine Antworten, leider werde ich vom ARM nicht loskommen, ist nun mal ne vorgegebene Studienarbeit. Mit Assembler hatte ich in der Tat noch nie etwas zu tun. Gibt es da gerade im Hinblick auf Interrupts Bsp., über die man sich langsam herantasten kann? Brauch ja ne vernünftige Beschäftigung während den Feiertagen ;-) Frohes Fest, Max
mal ein hinweis: wie oft feuert denn dein timer interrupt pro sekunde ? deine ereignisfunktion/int-handler ist ja voller warteschleifen... das sollte man in einer interruptfunktion unbedingt vermeiden mach es lieber so, daß der interrupt alle paar hundert ms feuert, und du in der ereignisfunktion/int-handler nur den pin umschaltest also in etwa so ein verhalten: - int kommt: led aus - int kommt: led an - int kommt: led aus usw.
Danke für die Antwort, die Delays sind lediglich aufgrund meiner 1000 Versuche, das Ding zum Laufen zu bringen, hinzugekommen ;-) Die Brauch ich später auch nicht. Der TC wird mit MCK/1024 betrieben ( MCK ~ 48MHz ), dieser hat einen 16bit Counter. Immer bei Inkrementierung sollte der interrupten. Da komm ich auf so ca. 1,4 sec. Mit Pin-Umschaltung wird auch lediglich der aller erste Interrupt angestoßen?! VG Max
>Mit Pin-Umschaltung wird auch lediglich der >aller erste Interrupt angestoßen?! Der Interrupt wird durch den Timer ausgelöst, und die Interrupt-Routine (bei Dir "Ereignisfunktion") toggelt die LED.
ach übrigens: viele übersehen wichtige Parameter des Timers, da diese oftmals mehrere Funktionen zur Verfügung stellen. Deshalb ist es immer sinnvoll in solchen Fällen das Kapitel über den Timer im Datenblatt nochmal durchzugehen: Wichtige Stichpunkte: Überlaufverhalten, Interrupt-Maske etc.
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.