Schleifen im Interrupt

OP #1283706
Lesenswert?

Hallo! Also ich habe mal in einem Praktikum beigebracht bekommen, im 
Interrupt möglichst wenig zeitaufwändige Dinge reinzuprogrammieren.

Ich habe hier jetzt einen OV-Interrupt, der jede Millisekunde auslöst. 
Ich will die Laufvariable i hochzählen und auf i<255 prüfen. Wenn 
i>=255, soll ein Flag gesetzt werden, was sich dann aufs main-Programm 
auswirkt.

Meine Frage:
Zähle ich im interrupt nur die Variable hoch, und Prüfe dann im main auf 
i<255?? Oder kann ich die Prüfung auch noch in der ISR machen?

Hier der Quelltext:
1
  mov A,i      ;i in Akku
2
  cjne A,255d,UNGLEICH;Test auf Gleichheit
3
   ;i=255, also wurde soeben der 256. Messwert addiert
4
  setb ausgabe   ;ausgabe-bit auf 1 setzen
5
  mov i,#0       ;i auf 0 setzen
6
  jmp ENDE
7
 UNGLEICH: ;wenn i != 255 (also kleiner)
8
  mov A,i
9
  add A,#1  
10
  mov i,A
11
 ENDE:
Gast #1283720
Lesenswert?

Hi

Wozu ein Vergleich. Wenn du ein Byte hochzählst kommt es bei 255+1 zu 
einem Überlauf. Im allgemeinen wird das Carry-Flag gesetzt und das Byte 
ist wieder Null.

>ähle ich im interrupt nur die Variable hoch, und Prüfe dann im main auf
>i<255?? Oder kann ich die Prüfung auch noch in der ISR machen?

Wenn du in deiner ISR nichts weiter drin hast ist es eigentlich egal.

MfG Spess
#1283722
Lesenswert?

Jürgen Hems schrieb:
> Hallo! Also ich habe mal in einem Praktikum beigebracht bekommen, im
> Interrupt möglichst wenig zeitaufwändige Dinge reinzuprogrammieren.

Ja, das hat den Sinn, daß sonst (je nach Architektur) andere Interrupts, 
die während der Abarbeitung der Serviceroutine des Ersteren auftreten, 
verloren gehen könnten.

> Ich habe hier jetzt einen OV-Interrupt, der jede Millisekunde auslöst.
> Ich will die Laufvariable i hochzählen und auf i<255 prüfen.

Du kannst Dir, mit Kenntnis der Taktfrequenz, Kenntnis der zeitlichen 
Länge der ISR (Laufzeit der Assemblerbefehle addieren), Auftreten 
anderer Interrupts und deren Länge, ausrechnen ob es sich ausgeht.

> Zähle ich im interrupt nur die Variable hoch, und Prüfe dann im main auf
> i<255?? Oder kann ich die Prüfung auch noch in der ISR machen?

Besser ist das (es ausserhalb der ISR zu machen).

Gruß, Iwan
Gast #1283733
Lesenswert?

Das Prüfen ist so kurz, dass du es im Interrupt machen kannst, und zwar 
so, dass du bei 0 (was 256 entspricht) ein Bit setzt, welches dem 
Hauptprogramm mitteilt, dass der Wert erreicht ist.
Der 8051 bietet dafür ja den JZ- bzw. JNZ-Befehl.

Also im Interrupt:
1
...             ;Variable hochzählen
2
mov a,variable  ;Variable auf 256 prüfen
3
jnz INT_ENDE    ;Wenn Variable kleiner als 256, Interrupt verlassen
4
setb complete   ;ansonsten complete-Flag setzen
5
...

Denk an Sichern der verwendeten Register (PUSH/POP).
Ob der Sonderfall variable=0 (nicht 256) eintreten kann, hängt von 
deiner restlichen Software ab.

Generell sollte, wie du richtig gesagt hast, jeder Interrupt so kurz wie 
möglich sein. Schleifen sind also zu vermeiden, was auch in nahezu 100% 
aller Fälle geht.

Ralf
Gast #1283735
Lesenswert?

Hallo,
auf Deinen asm code kann ich nicht eigehen, aber hier
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Datenaustausch_mit_Interrupt-Routinen
wird das selbe mit C besprochen. Dort wird auch die Prüfung im main und 
nicht in der ISR gemacht. (Obwohl auch im ISR kurz geprüft wird und dann 
erst hochgezählt wird). es ist wahrscheinlich schnurz, wichtig ist nur 
das die eigentliche routine die gestartet werden soll nicht in der ISR 
steht.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren