PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Timer-Programmierung



RHS
13.06.2005, 10:57
Hallo,

wie handhabt Ihr folgendes:

Ich benötige "Ereignisse" in 1, 10 und 60 Sek. Abstand. Nennen
wir die mal E1, E10 und E60.

Wie gehe ich ab besten vor, wenn ich in der Main-Loop diese Ereignisse
abarbeiten will? Soll ich bspw. einen Timer mit 1 Sekunde Auflösung
installieren und in diesem dann einen Zähler für E10 bzw. E60
inkrementieren? Scheint mir am sinnvollsten ...

Gleiches Problem, etwas abgewandelt: aus der Main-Loop springe
ich mit Gosub in irgendein Unterprogramm. Wie stelle ich dort sicher,
das die o.g. "Ereignisse" abgearbeitet werden, wenn ich nicht vor-
aussehen kann, wie lange der Benutzer (es handelt sich um eine Menü)
in diesem Unterprogramm verbleibt?

Danke: - Reinhard -

Vitis
13.06.2005, 12:31
Der Timer löst eine Interrupt-Routine aus, am einfachsten jede 1 sekunde.
dort inkrementierste ne variable, und baus aus if - then ne verzweigung,
die die subprozeduren e1 e10 e60 aufruft.

ON interrupt label

Remarks

Interrupt INT0, INT1, INT2, INT3, INT4,INT5, TIMER0 ,TIMER1, TIMER2, ADC , EEPROM , CAPTURE1, COMPARE1A, COMPARE1B,COMPARE1. Or you can use the AVR name convention :

OC2 , OVF2, ICP1, OC1A, OC1B, OVF1, OVF0, SPI, URXC,
UDRE, UTXC, ADCC, ERDY and ACI.
Label The label to jump to if the interrupt occurs.

die interrupt-routinen werden unabhängig von der main-loop routine abgearbeitet. der avr springt also beim timer-ereigniss immer in die entsprechende behandlungsroutine, arbeitet diese ab und springt dann zurück.

PicNick
13.06.2005, 15:57
Wenn du die Events nicht komplett in der Interrupt-Routine abarbeiten kannst, darfst du deinen User ganz einfach nicht ewig in seinem Unterprogramm bleiben lassen.
d.h. du mußt die die Position im Menu merken und wieder zurück ins main-programm. erst wenn der User irgendwas drückt, gehts du wieder ins Menu dorthin zurück.

RHS
13.06.2005, 18:37
Der Timer löst eine Interrupt-Routine aus, am einfachsten jede 1 sekunde.
dort inkrementierste ne variable, und baus aus if - then ne verzweigung,
die die subprozeduren e1 e10 e60 aufruft.


Hallo Vitis,

bzgl. Timer und Interrupt-Routine ist mir das soweit klar. Aber wenn
ich aus der Interrupt-Routine heraus mit Gosub die Sub-Prozeduren
aufrufe, springe ich doch anschließend wieder in die Interrupt-Routine
zurück? Die Laufzeit der Interrupt-Routine wäre dann doch zzgl. der
für die Sub-Prozeduren zu sehen ...

Mein Ansatz war daher, in der Interrupt-Routine nur Zähler für E1, E10
und E60 zu inkrementieren und dann in der Main-Loop mit IF/Then eine
entsprechende Verzweigung aufzubauen. Dann dürfte die Laufzeit der
Sub-Prozeduren keine Rolle spielen ...

Allerdings kann der Anwender die Main-Loop auch verlassen (Menü) und
ich würde dann trotzdem gerne die Sub-Prozeduren weiterhin aus-
führen.

Allgemein wird doch gesagt, die Laufzeit der Interrupt-Routine soll
möglichst kurz sein. Wenn ich nun hingehe und in der Interrupt-Routine,
oder einer von dort aufgerufenen Sub-Prozedur, bspw. Ports umschalte,
oder den AD-Port abfrage, oder I2C-Befehle absetze ist das dann zeit-
kritisch in Bezug auf "neuer Interrupt kommt, alter aber noch nicht abgearbeitet" zu sehen?

Muss ich wohl testen, ob das so geht ...

@PickNick
Menü merken und wieder zurück etc. ist 'nen bisschen aufwendig ... Ich
könnte aber wohl die Menü-Tastaturabfrage so ändern, das die Events
auch dort abgearbeitet werden.


- Reinhard -

Vitis
14.06.2005, 07:22
hi Reinhard,

dann wird deine main-loop Routine aber auch ganz schön lang ... hmm naja,
die E(x)-Funktionen kommen ja nur im falle der variablendeckung ins spiel,
ja das kann klappen.

die avrs haben keine interrupt prioritätslisten geb ich noch zu bedenken,
ein überschneiden würd ich halt versuchen zu vermeiden, aber das haste
ja auch schon erkannt.

ich würd die e(x) funktionen doch in subprozeduren packen und dann von
der main-loop-routine aus starten, das macht den code etwas übersichtlicher,
an der funktion selbst ändert sich dadurch ja nix, aber du kannst die
funktionsaufrufe von jedem teil des listings aus starten, was das debuggen
einfacher macht und gibt ne bessere b-note für stil ;)
aus den sub-prozeduren heraus werden die interrupts genau so wie aus der
main-loop heraus angesprungen.
im übrigen haste nen sekündlichen timerüberlauf, da muß die subprozedur
schon sehr lang sein, das die in der zeit nicht abgearbeitet werden kann.

auch ne alternative zu if then:

Syntax
SELECT CASE var
CASE test1 : statements
[CASE test2 : statements ]
CASE ELSE : statements
END SELECT


Remarks

Var Variable. to test
Test1 Value to test for.
Test2 Value to test for.
You can test for conditions to like:
CASE IS > 2 :
Another option is to test for a range :
CASE 2 TO 5 :

RHS
14.06.2005, 08:10
im übrigen haste nen sekündlichen timerüberlauf, da muß die subprozedur
schon sehr lang sein, das die in der zeit nicht abgearbeitet werden kann.


Hallo Vitis,

mir fehlt vermutlich noch etwas das Gefühl dafür, wir lange ein AVR (bei
mir Mega32) an einer Sub so festhängt. Mal ein paar Beispiele, was ich
machen möchte: sekündlich Meßwerte abfragen (Temperatur über I2C,
Portzustände, ADC), alle 10 Sekunden Werte in EERAM speichern etc.

Vermutlich langweilt sich der Mega32 aber dabei nur ... ;-).

Ich werd's jetzt erst mal so machen, das ich die Sub's aus der Interrupt-
Routine aufrufe. Dann brauche ich das Menüsystem nicht ändern und ich
habe nur einen zentralen Aufruf.

Danke für Deine Ideen.

- Reinhard -