www.mikrocontroller.net

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


Autor: Moritz Greif (moritz-)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
TCNT0 = 0

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Moritz Greif (moritz-)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Moritz Greif (moritz-)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Moritz Greif (moritz-)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Moritz (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...



Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.