PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : interrupt und variable inkrementieren



crusader
25.11.2004, 14:58
Hi, hab mal ne kurze frage, hoffentlich gibts auch bald ne kurze antwort ;)

möchte eine variable bei jedem interrupt aufruf inkrementieren.

wenn ich aber einfach "a=a+1" in meine inerruptroutine einfüge,
steht die variable a leider nicht für mein hauptprogramm oder subroutinen zur verfügung oder bleibt konstant.

wie muss ich a deklarieren, das ich sie global verwenden kann?

thx im vorraus.

PicNick
25.11.2004, 15:09
Bei C schreibt man "static" dazu, (innerhalb eines Moduls)
static int a = 0;
bei Basic irgendwas mit "global", denk' ich, da mußt man aber nachschauen. Type "Help" for help mfg :-)

crusader
25.11.2004, 15:24
Hier mal mein Problem...

Ich will, das mein Robi 1000 schritte gerade aus macht,
und dann eine Linksdrehung dazu soll ein rad 45 schritte in ne andere richtung machen. sprich das programm hängt 45 schritte in der if schleife und danach springt es aus der subroutine.
und dann wieder 1000 geradeaus.
usw...


wie zähle ich jetzt 45 interupts??




Declare Sub Drehen_links()

$regfile = "m32def.dat"
$crystal = 16000000

Dim Z As Integer

Config Timer1 = Timer
On Timer1 Timer_irq
Tccr1b = Tccr1b Or &H05
Timer1 = 65458

Z = 0

Do

If Z > 1000 Then Call Drehen_links

Loop

End


Timer_irq:

Toggle ...
Z = Z + 1

Return


Sub Drehen_links()

...
If Z > 45 Then
Z = 0
End If
End Sub

BASTIUniversal
25.11.2004, 15:30
Also ich hab das in Bascom mit ähnlich gemacht (bei Überlauf wird x inkrementiert) und hab die Variable auch nicht großartig anders deklariert!
Hier mal die Variante die ich verwende:

On Int1 OnInt1 'Bei Interrupt 1 gehe zu OnInt1
Dim a as byte 'Ganz normal a als Byte deklarieren

Do
Loop 'Hauptprogramm

OnInt1 'Wenn Interrupt 1 ausgelöst wird
incr a 'a um 1 erhöhen
Return 'Zurück zum Hauptprogramm

End

Ich weiß jetzt nicht ob's bei nem Interrupt anders als bei nem Timer ist, aber bei mir tut's!

MfG
Basti

PicNick
25.11.2004, 15:55
Wenn "drehen links" dran ist , hat Z einen Wert von > 1000.
Wenn dir Funktion dann auf > 45 fragt, wird dich das Gerät nicht lange drehen, fürcht ich. mfg :)

crusader
25.11.2004, 17:56
muss mir das morgen nochmal ansehen,
wäre natürlich blöd, wenns so wäre. ](*,)
kann sein, das ich auch nen z=0 am anfang der subroutine stehen habe.
trotzdem noch die allgemeine frage,
wird die variable z also einfach von der interrup routine an das hauptprogramm übergeben, ohne, das ich sie speziell deklarieren muss?
oder muss ich sie dafür mit variablenübergabe definieren?

DECLARE SUB Drehe_links(z as integer)

PicNick
25.11.2004, 19:08
Nö, die Variable ist entweder global für Interrupt, Main und Subroutine oder das Ganze klappt eh nicht.
Eine (mögliche) Tücke noch: eine Variable, die über 1000 geht, ist offensichtlich länger als ein Byte. Und während du auf Null setzten willst, zählt ja der Timer weiter. Dabei kann es durch gefinkelte Überlappungen zu Datenmüll kommen (kommt auf den Kompiler an) Um sicher zu sein, ein Tip:
Definiere zusätzlich eine Variable LOCK, normalerweise null.
Veränderst du im Normalprogramm den Wert von Z, setz' LOCK = 1, ändere Z, dann wieder LOCK = 0.
In der Interrupt routine zählst du nur dann auf Z, wenn LOCK auf Null steht. Aber nicht darauf warten (--> Katastophe), sondern einfach rücksprung aus Irpt).
Das ist sicher einer drauf, aber nummero sicher mfg :-)

crusader
26.11.2004, 11:51
Also... funzt jetzt
zum einen war da noch ein z= 0 am anfang der routine.

es lag aber daran, das ich mit dieser "if z > 45" konstruktion nicht wirklich viel erreicht habe, höchstens den direkten sprung danach aus der subroutine.
brauchste ja ne schleife und keine if- abfrage.
hab das jetzt durch "do loop until z>45" ersetzt... funzt jetzt auch...

trotzdem danke für die antworten und direkt mal den nächsten thread eröffnen.