Hallo, ich habe da eine Frage ich benutze einen Atmega 128L. Auf meinem Mikrocontroller Läuft ein Timer der nach einer gewissen zeit einen Interrupt auslöst und dort eine Funktion aufruft die so ca 100ms dauert. In der Zwischenzeit kann aber ein weiterer Intterrupt auftreten. Kann man sich diesen Interrupt irgendwie merken und in nach dem Ablauf des anderen Interrupts aufrufen. Da dieser den Ersten Interrupt nicht unterbrechen darf. Wäre nett wenn jemand mir da helfen könnte Grüße Losti
Falscher Ansatz. Die Interrupt-Routine darf keine 100ms dauern. Besser: Im Interrupt ein Flag setzen und in der Hauptschleife abhängig vom Flag den 100ms Job laufen lassen.
Trotzdem ja, ein Interruptflag wird beim Interrupt automatisch gesetzt bleibt solange gesetzt, bis die entsprechende Behandlungsroutine aufgerufen wurde.
> Wäre nett wenn jemand mir da helfen könnte
Ja, das Datenblatt.
Wenn ein Interrupt enabled ist, bleibt der solange anstehen, bis das
zugehörige Interrupt-Flag zurückgesetzt wird (und das passiert idR durch
eine Interaktion der Software).
> Interrupt ... Funktion ... die so ca 100ms dauert.
Das darf nicht sein, das ist eine extrem unsaubere Programmierung.
Denn was nicht gespeichert wird, ist die Information, wie_oft der
Interrupt (z.B. ein Timer-Überlauf) in dieser Zeit aufgetreten ist. du
weißt also nach den 100ms nur, dass mindestens 1 mal die
Interruptbedingung zugetroffen hat.
Hallo, korrekter ist es, wenn man eine globale Variable dazu verwendet, sich zu merken, dass der Interrupt da war (die Variable setzt man im Interrupt auf z.B. 1). Diese Variable kann man dann im Hauptprogramm oder auch wo anders zyklisch abfragen, wenn man gerade Zeit dazu hat und wenn sie gesetzt ist, arbeitet man das ab, was der Interrupt auslösen soll. Wenn man das gemacht hat, setzt man die Variable zurück, so dass die Routine erst beim nächsten Interrupt wieder ausgeführt wird. So vermeidet man, dass der Interrupt unnötig lange dauert. Grüße, Peter
Hallo danke schonmal für die schnelle Auskunft mein Problem ist allerdings das ich sobald der Interrupt auftritt sofort darauf reagieren muss also dieser 100ms ablauf erfolgen muss. Mir ist schon klar das das sehr unsauber ist aber hat jemand eine andere ideee. Das Problem ist das das Hauptprogramm natürlich gerade etwas anderes bearbeiten kann und dafür auch etwas zeit braucht. In dem Fall wären von den 100 ms schon 15 - 25 verbraten. Was auf keinen Fall passieren darf.
Tja - dann hilft, im 100ms Interrupt Handler die Interrupts wieder freizugeben und genug Stack vorzusehen. Ein RTOS oder ein top/bottom-half Handler wäre wohl ein zu grosser Schritt.
Hallo,
> 100ms ablauf erfolgen muss
kann man nicht die 100ms etwas optimieren? Was dauert denn so lange?
>sofort darauf reagieren muss also dieser 100ms ablauf erfolgen muss.
Innerhalb dieser 100ms brauchst Du also Mikrosekunden genaues Timing?
Das halte ich für ein großes Gerücht!
Zeig doch mal Deine Interruptroutine; dann relativieren sich Deine
Anforderungen sofort.
Das ist halt ein Zeitschlitz in dem etwas verarbeitet werden muss und den muss ich feste einhalten
>Das ist halt ein Zeitschlitz in dem etwas verarbeitet werden muss und >den muss ich feste einhalten Solche Probleme haben die meisten Leute hier, nur daß die Schlitze nicht 100ms sondern 100µs groß sind. Aber ich sehe schon, Dein Projekt ist geheim :-)
>sobald der Interrupt auftritt sofort darauf reagieren >muss also dieser 100ms ablauf erfolgen muss. Die Lösung Deines Problems könnte davon abhängen, was mit "sofort" gemeint ist. Es macht einen Unterschied, ob es "innerhalb weniger Taktzyklen" bedeutet, oder "innerhalb einer Millisekunde", denn ersteres ist auch für den µC schnell, letzteres aber noch eher langsam.
Da kommt jemand mit Zingeltaskink nicht zurecht und da wird ihm dann gleich Multitaskink empfohlen. Prima Vorschlag!
@ Gast (Gast) >Da kommt jemand mit Zingeltaskink nicht zurecht und da wird ihm dann Single? >gleich Multitaskink empfohlen. >Prima Vorschlag! Und ob. Denn in Wirklichkeit ist auch das Singletasking ein Multitasking. UNd es wird dazu auch ein anderer Denk- und Programmieransatz benötigt. Lies mal den Artikel. MFg Falk
Hans Klemer wrote: > Hallo danke schonmal für die schnelle Auskunft mein Problem ist > allerdings das ich sobald der Interrupt auftritt sofort darauf reagieren > muss also dieser 100ms ablauf erfolgen muss. Erzähl dochmal, was alles in diesen 100ms passieren muß. Ich kann nicht glauben, daß diese 100ms voll mit CPU-Berechnungen ausgelastet sind. Und darin liegt auch der Lösungsansatz: Du hast nach bestimmten Zeiten bestimmte kurze Dinge zu machen. Dann startest Du einfach nur nen Timerinterrupt mit dem Delayintervall für die nächste Sache. Dann machst Du sie und setzt den Timer auf das nächste Intervall. In der Zwischenzeit kann sich das Main voll austoben. Und damit Du weißt, welches nun die nächste Sache ist, nimmst Du eine Statemaschine, d.h. eine Variable zählt die States hoch und in ner switch/case Anweisung stehen die einzelnen Aktionen. Anbei mal ein Beispiel, wie so eine Statemaschine im Hintergrund 1-wire Sensoren ausliest, ist für nen 8051 in C geschrieben. Die Statemaschine befindet sich im Timer 0 Interrupt und macht alle 1-wire Timings. Peter
Wenn man ganz fies sein will (geht natürlich nur in ASM wirklich gut:
1 | timer_int: |
2 | ldi temp, HIGH(timer_funktion_100ms) |
3 | push temp |
4 | ldi temp, HIGH(timer_funktion_100ms) |
5 | push temp |
6 | reti |
7 | |
8 | |
9 | main: |
10 | . |
11 | . |
12 | . |
13 | rjmp main |
14 | |
15 | |
16 | |
17 | timer_funktion_100ms: |
18 | . |
19 | . |
20 | ret |
Das reti führt dazu das der AVR zu der timer_funktion_100ms springt, das ret am Ende der Funktion springt wieder an die Stelle im Hauptprogram wo der Interupt dieses unterbrochen hat.
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.