Forum: Mikrocontroller und Digitale Elektronik Interrupt merken? ATMega128L


von Hans K. (losti85)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

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.

von Sven P. (Gast)


Lesenswert?

Trotzdem ja, ein Interruptflag wird beim Interrupt automatisch gesetzt 
bleibt solange gesetzt, bis die entsprechende Behandlungsroutine 
aufgerufen wurde.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> 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).

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> 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.

von Peter Diener (Gast)


Lesenswert?

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

von Falk B. (falk)


Lesenswert?

Siehe Interrupt

von Hans K. (losti85)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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.

von Peter (Gast)


Lesenswert?

Hallo,
> 100ms ablauf erfolgen muss
kann man nicht die 100ms etwas optimieren? Was dauert denn so lange?

von Gast (Gast)


Lesenswert?

>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.

von Hans K. (losti85)


Lesenswert?

Das ist halt ein Zeitschlitz in dem etwas verarbeitet werden muss und 
den muss ich feste einhalten

von Gast (Gast)


Lesenswert?

>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 :-)

von Gast (Gast)


Lesenswert?

>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.

von Falk B. (falk)


Lesenswert?


von Gast (Gast)


Lesenswert?

Da kommt jemand mit Zingeltaskink nicht zurecht und da wird ihm dann 
gleich Multitaskink empfohlen.
Prima Vorschlag!

von Falk B. (falk)


Lesenswert?

@  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

von Peter D. (peda)


Angehängte Dateien:

Lesenswert?

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

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

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.

von Hans K. (losti85)


Lesenswert?

Danke für die Hilfe habt mir gut weitergeholfen. Gruß Losti

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.