Forum: Mikrocontroller und Digitale Elektronik Timer0 als Counter ohne reti zurücksetzen (Assembler, mega8


von Moritz G. (moritz-)


Lesenswert?

Hallo!
Ich habe im Forum schon nachgeschaut, so ganz gefunden was ich wollte 
hab ich noch nicht. Also, es geht um den Timer0 (auch Timer1, kommt ja 
dann aus selbe hinaus) im ATmega8, der folgender massen konfiguriert 
wurde:

        ldi     temp, 0b00000111    ; CS0x setzen: steigende flanke
        out     TCCR0, temp
        ldi     temp, 0b00000001   ; TOIE0: Interrupt bei Timer Overflow
        out     TIMSK, temp
        sei

und zwar wird diese konfiguration ausgeführt, wenn ein Schalter gedrückt 
wird. Der Timer ist danach auch in Bereitschaft, und zählt die Impulse 
an seinem Eingang, bei Impuls 256 springt er in den Overflow Handler.
Soweit Sogut.
Nur: wie kann ich den Timer auf null zurücksetzen, und wieder starten, 
und zwar an einem Ort wo ich will (mit reti springt er ja dorthin ins 
programm zurück, wo der interrupt aufgetreten ist, nur da will ich nach 
Aufruf des Overflowhandlers nicht mehr zurück!!!)

Habt Ihr da eine Idee?

von Rahul, der Trollige (Gast)


Lesenswert?

TCNT0 = 0

von Falk (Gast)


Lesenswert?

@Moritz Greif

>Nur: wie kann ich den Timer auf null zurücksetzen, und wieder starten,

Wurde oben scho gesagt.

>und zwar an einem Ort wo ich will (mit reti springt er ja dorthin ins
>programm zurück, wo der interrupt aufgetreten ist, nur da will ich nach
>Aufruf des Overflowhandlers nicht mehr zurück!!!)

Das ist der Sinn von INTERRUPT Handlern. Die werden IMMER mit RETI 
beendet. Wenn du deinem Programm, welches normalerweise in einer 
Endlosschleife läuft, mitteilen willst, dass der Overfolw erreicht ist 
und nun was anderes gemacht werden soll, dann must du in deinem Interrup 
eine Variables setzen. Diese kann dein Programm in der Endlosschleife 
abfragen und entsprechen reagieren. Alles andere ist Murks.

MFG
Falk

von Moritz G. (moritz-)


Lesenswert?

>dann must du in deinem Interrup
>eine Variables setzen. Diese kann dein Programm in der Endlosschleife
>abfragen und entsprechen reagieren.

wie kann man in einem interrupt eine Variable setzen?
Abfragen wird schwierig, da es um einen genauen Frequenzmesser geht, und 
die Schleife die durch den T0 - Overflow unterbrochen/beendet wird, ist 
etwas zeitkritisch...!

@Rahul, der Trollige:

So hab ich das ausprobiert, nur hats irgendwie nicht schön geklappt. 
Wird der Timer nach diesem Befehl sofort wieder gestartet (bzw. zählt er 
ab da, und löst beim überlauf den interrupt aus? Das wäre wichtig zu 
wissen!

clr temp1
out tcnt0,temp1

Auf jeden Fall Vielen Dank (!!!) für die superschnellen Antworten!!!!!

Grüsse
Moritz

von Rahul, der Trollige (Gast)


Lesenswert?

>wie kann man in einem interrupt eine Variable setzen?

Genauso wie im Hauptprogramm.

>Wird der Timer nach diesem Befehl sofort wieder gestartet (bzw. zählt er
>ab da, und löst beim überlauf den interrupt aus? Das wäre wichtig zu
>wissen

Wieso sollte der Timer von da neu starten? Nein, er läuft einfach 
weiter.
Wenn du ihn stoppen willst, musst du "CS0x" = 0 setzen.

von Falk (Gast)


Lesenswert?

@Moritz Greif

>wie kann man in einem interrupt eine Variable setzen?

???
Genauso wie im normalen Program.

>Abfragen wird schwierig, da es um einen genauen Frequenzmesser geht, und
>die Schleife die durch den T0 - Overflow unterbrochen/beendet wird, ist
>etwas zeitkritisch...!

Dann nimm keinen Interrupt sondern Polling. Du kannst nämlich das Bit 
TOV0 im Register TIFR auch einfach auslesen bzw. löschen.

MfG
Falk

von Karl H. (kbuchegg)


Lesenswert?

> Abfragen wird schwierig, da es um einen genauen Frequenzmesser
> geht, und die Schleife die durch den T0 - Overflow
> unterbrochen/beendet wird, ist etwas zeitkritisch...!

Vielleicht wäre dann ein Input Capture am Timer1 die
bessere Wahl.

von Moritz G. (moritz-)


Lesenswert?

Ah, jetzt weiss ich was ihr meint: im interrupt-Handler-Unterprogramm 
eine "Status-Variable" für Timer Overflow setzen, und die dann in der 
mainloop immer abfragen...hm könnt ich machen, aber es gibt anscheinend 
keinen Befehl zum kompletten Stoppen/rücksetzen des Timers und dann wann 
man will, meinetwegen durch ne komplette Neukonfiguraion des timers, ihn 
wieder zu starten?
Ich dachte es eigentlich so ungefähr:

;----------------------------------------------------------

hauptprogramm:
;...--bei Tastendruck springe zu machwas
rjmp hauptprogramm

machwas:

ldi     temp, 0b00000111      ; Konfiguriere den Timer
out     TCCR1B, temp
ldi     temp, 0b00000100  ;Timer soll bei Überlauf zu Timer_Overflow
out     TIMSK, temp       ;springen
sei

machwas_loop:
...                                  ;zeitkritischer loop
rjmp machwas_loop


Timer_Overflow:
...

So hier muss der Timer gestoppt werden, mit reti würde er ja dann 
irgendwo in machwas_loop zurückspringen!! Ich will aber erst z.b. zu 
hauptprogramm oder so...

von Moritz G. (moritz-)


Lesenswert?

@Karl Heinz:
Input Capture?

Ich hab das gleiche Verfahren mit Überlauf-Interrupt auch beim Timer1 
benutzt, für den Frequenzmesser...   ( übrigens die Berechnung ist jetzt 
perfekt, deine Subtraktionsmethode fürs LCD hats echt gebracht, ich 
stell den fertigen Code demnächst ins Forum, nur muss ich diese 
Timerreset-Sache lösen....)

gruss moritz

von johnny.m (Gast)


Lesenswert?

Wenn Du nicht mit einem Prescaler arbeitest, sondern wie in Deinem 
obigen Code mit einem externen Taktsignal, sollte ein Nullsetzen des 
TCNTxy ausreichen, um den Timer in Startposition zu bringen. Nur wenn Du 
einen Takt vom Prescaler nimmst, musst Du zusätzlich den Prescaler 
zurücksetzen, um den Timer wieder zu synchronisieren...

von Moritz (Gast)


Lesenswert?

nee, der externe Takt, erhöht eins zu eins bei steigender flanke den 
Timerwert, ich brobiers nochmal mit dem  tcnt0 auf null setzen..
Sonst mach ich halt doch vielleicht das oben gesagte mit der 
Variablen...



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.