Forum: Mikrocontroller und Digitale Elektronik Attiny85 Timer1 TOV1 Verständnisfrage


von Tom (Gast)


Lesenswert?

Habe lange Erfahrung mit ATmega und ATxmega, habe aber mit ATtiny so gut 
wie keine Erfahrung. Jetzt ist mir ein ATtiny85 über den Weg gelaufen 
und ich habe ein paar Tests damit gemacht. Dabei ist mir aufgefallen, 
das der Timer1 anderst gestrickt ist als der Timer0 und sich auch 
anderst verhält, was ich mir nicht erklären kann. Speziell geht es hier 
aber nur um das Überlaufflag TOV1. Das es auch noch andere Änderungen 
des Timer1 gegenüber Timer0 gibt, habe ich schon im Datenblatt nachlesen 
können.

Wenn ich z.B. Timer0 des ATtiny85 verwende kann ich damit ganz normal 
eine Zeitschleife ausführen, so wie ich das auch von Atmega usw. her 
kenne. Wie z.B. diese für den Timer0...
;----Timer Vorteiler einstellen und Timer läuft...
ldi temp, 0b00000101
out TCCR0B, temp
;----Programmschleife LED Blinker...
test:
sbi port_led, led_1
rcall warte_100ms
cbi port_led, led_1
rcall warte_100ms
rjmp test
;----Unterprogramm Warteschleife...
warte_100ms:
ldi temp, 0b00000000
out TCNT0, temp
in temp, TIFR
ori temp, 0b00000010
out TIFR, temp
warte_loop:
in temp, TIFR
sbrs temp, TOV0
rjmp warte_loop
ret

Ob mit dieser Warteschleife wirklich 100mS rauskommen oder nicht, ist 
erst mal egal... darum geht es auch nicht.

Wenn ich aber das selbe mit dem Timer1 mache, (Natürlich auch die 
entsprechenden Verwendung der Timer1 Register und des TOV1 Bit2 des 
TIFR!) Dann wird die Warteschleife "warte_100ms" das erste mal 
ordentlich durchgeführt, aber immer und grundsätzlich das zweite mal 
nicht! Grundsätzlich wird die Warteschleife immer nur jedes zweite Mal 
richtig verarbeitet.
Jetzt habe ich feststellen können, das das Überlaufbit TOV1 bei jedem 
zweiten Durchlauf der Warteschleife nicht gelöscht wird, obwohl ich eine 
"1" auf das Bit2 des TIFR schreibe und die Wartezeit somit nicht 
stattfindet.
Im Datenblatt habe ich unter der Registerbeschreibung für TIFR folgendes 
gefunden...
"TOV1 is cleared, after synchronization clock cycle, by writing a 
logical one to the flag".
Daraufhin habe ich das Problem so gelöst, das ich zweimal hintereinander 
das TOV1 flag mit einer "1" beschreibe und dann ist es auch wirklich 
immer gelöscht und das primitive Testprogramm funktioniert.

Nun aber zu meiner eigentlichen Frage:
Was muss ich mir unter "after synchronization clock cycle" denn 
vorstellen? "after" was denn?
Aus dem Datenblatt werde ich nicht schlau, was es mit diese 
synchronisation aufsich hat, wie bzw. warum sich diese auf das löschen 
des Überlaufflags auswirkt und wie diese arbeitet/funktioniert und wie 
man das TOV1 Bit denn dann richtig löscht?

Könnte mir bitte jemand mit ein paar Worten Beschreiben warum das so 
beim Timer1 des ATtiny85 (oder aller ATtinys?) ist?

von S. Landolt (Gast)


Lesenswert?

Hängt wohl damit zusammen, dass Timer1 auch asynchron laufen kann. 
Einfach nach dem 'out TIFR' ein paar Takte warten, 3 scheinen zu 
reichen.

von c-hater (Gast)


Lesenswert?

Tom schrieb:

> in temp, TIFR
> ori temp, 0b00000010
> out TIFR, temp

Das ist definitiv unsinniger Code. Und nicht nur beim ATtiny, sondern 
bei jedem AVR8. Lies' bitte das DB und versuche, zu verstehen, was da 
zum Thema "strobe bits" geschrieben wird (leider ohne den Begriff zu 
erwähnen).

Korrekt wäre:

> ldi temp, 0b00000010
> out TIFR, temp

Naja, jedenfalls wäre es richtig, wenn auf Bitposition 1 tatsächlich das 
TOV1-Flag wäre. Ist es aber nicht...

von Tom (Gast)


Angehängte Dateien:

Lesenswert?

S. Landolt schrieb:
> Hängt wohl damit zusammen, dass Timer1 auch asynchron laufen kann.
> Einfach nach dem 'out TIFR' ein paar Takte warten, 3 scheinen zu
> reichen.

Danke für den Tipp, der auch wirklich so funktioniert.
Scheinbar braucht der Timer1 halt wirklich 3 ganze Taktzyklen, bevor 
eine Änderung des TIFR TOV1 Flags durch den "out TIFR" Befehl bewirkt 
wird.

Ich habe jetzt mal meinen Programmcode mit 3 NOP´s abgeändert und das 
funktioniert auch! Aber halt auch wirklich nur mit 3 NOP´s. Wenn ich nur 
2 NOP´s mache dann geht es wieder nicht.

in temp, TIFR
ori temp, 0b00000100
out TIFR, temp
nop
nop
nop

Also dann verstehe ich auch wie die Zeichnung im Anhang bzw. von Seite 
83 des Datenblattes zu verstehen ist.
Hier sind es zuerst ein halber Takt, dann ein ganzer Takt, dann nochmal 
ein ganzer Takt und zum Schluss nochmal ein halber Takt. Also treten 
dann immer die 3 Takte Verzögerung beim Timer1 auf, wenn im Datenblatt 
von "after synchronisation..." gesprochen wird.

Ich kann mir zwar noch nicht wirkich erklären, warum das so ist, aber es 
hilft doch zumindest das die Programme auch am Ende ohne Problem laufen.

Besten Dank noch mal für deinen Hinweis.

von S. Landolt (Gast)


Lesenswert?

Danke für die Rückmeldung!

Ich möchte aber doch auf c-haters Beitrag hinweisen, das
1
in temp, TIFR
2
ori temp, 0b00000100
3
out TIFR, temp
funktioniert hier zwar, ist aber eigentlich falsch, denn eventuell 
gesetzte weitere Flags in TIFR werden damit auch gelöscht, korrekt wäre
1
ldi temp, (1<<TOV1)
2
out TIFR, temp

von c-hater (Gast)


Lesenswert?

S. Landolt schrieb:

>
1
> ldi temp, (1<<TOV1)
2
> out TIFR, temp
3
>

Jepp, so schreibt das ein Programmierer, der diesen Namen verdient. Ok, 
über den Nutzen der Klammerung könnte man hier noch diskutieren, aber 
sie schaden zumindest nicht. Auch mein Konzept ist: lieber ein 
Klammerpaar zu viel, als eins zu wenig...

Hauptsache, es ist an der richtigen Stelle. Dann kann es Intentionen oft 
besser dokumentieren als jeder Kommentar (auch wenn es syntaktisch 
überflüssig ist).

Aber bei nur einem Term würde auch ich doch eher auf die Klammerung 
verzichten...

von S. Landolt (Gast)


Lesenswert?

Das schreiben meine zehn Finger automatisch, der Kopf ist daran nicht 
beteiligt ...

von S. Landolt (Gast)


Lesenswert?

Wenn wir aber schon bei unnötigen Hinweisen (oder gar Kritik?) sind: 
ich habe mir ein macro puti (darf auch anders heißen) definiert und 
schreibe folglich
1
  puti  TIFR, 1<<TOV1

von c-hater (Gast)


Lesenswert?

Tom schrieb:

> Scheinbar braucht der Timer1 halt wirklich 3 ganze Taktzyklen, bevor
> eine Änderung des TIFR TOV1 Flags durch den "out TIFR" Befehl bewirkt
> wird.

Nur dann, wenn er auch wirklich asynchron betrieben wird. Er kann ja 
durchaus auch ganz normal synchron betrieben werden und verhält sich 
dann auch ganz normal...

von Tom (Gast)


Lesenswert?

S. Landolt schrieb:

> ori temp, 0b00000100
> out TIFR, temp
> funktioniert hier zwar, ist aber eigentlich falsch, denn eventuell
> gesetzte weitere Flags in TIFR werden damit auch gelöscht, korrekt
> wäreldi temp, (1<<TOV1)
> out TIFR, temp

Danke für das Ansprechen des setzens des Bit´s für das TOV1 Bit.
Habe jetzt die Änderung auch so in meinem Programm gemacht. Ich wollte 
es besonderst gut machen, das eventuelle andere Bit´s im TIFR Register 
nioht beeinflusst werden. Aber wenn ich jetzt nochmal darüber nachdenke, 
ist es ja klar. Wenn ein Bit bzw. Flag im Register TIFR bereits durch 
irgendeine andere Aktion gesetzt worden wäre, würde ich dieses dann ja 
auch mit löschen, was natürlich vollkommen falsch wäre...

Somit muss ich sagen, das auch C-hater damit geholfen hat.

Danke nochmals für die Hinweise.

von S. Landolt (Gast)


Lesenswert?

Haben Sie das mal ausprobiert, c-hater?

von Tom (Gast)


Lesenswert?

c-hater schrieb:

>
> Nur dann, wenn er auch wirklich asynchron betrieben wird. Er kann ja
> durchaus auch ganz normal synchron betrieben werden und verhält sich
> dann auch ganz normal...

Ahhhhh.... Ich hatte gedacht, wenn ich nur den Vorteiler mit einem Wert 
aktiviere, das ich dann im synchronen Betriebsmodus bereits wäre. Wenn 
das nicht der Fall ist, wo oder wie oder was muss ich denn machen um in 
den Synchronen Modus zu gelangen? Welche Register, welche Bit´s müssen 
denn dafür gesetzt werden? Aus dem Datenblatt werde ich darüber nicht 
schlau...
Kannst du mir da mal bitte Helfen?

von S. Landolt (Gast)


Lesenswert?

Tja, Tom, so ist das mit den Überfliegern. Wahrscheinlich baut c-hater 
auf seine Erfahrungen, z.B. mit ATmega328_Timer2. Auf seine Antwort bin 
ich gespannt.

von c-hater (Gast)


Lesenswert?

S. Landolt schrieb:

> Haben Sie das mal ausprobiert, c-hater?

Praktisch? Ehrlicherweise: Nein. Polling ist nicht so mein Ding. Die 
meisten Sachen mache ich in ISRs. Und da brauche ich mich bei den Timern 
nie um den Reset des IRQ-Flags zu kümmern, das erledigt dann das System 
für mich. Ohne Zusatzkosten...

Wäre also wirklich denkbar, dass ich das falsch sehe, dass also die für 
den asynchronen Betrieb dokumentierten Delays auch im synchronen Betrieb 
wirksam sind. Werde ich bei nächster Gelegenheit mal verifizieren. 
Glücklicher Umstand: aktuelles Hobbyprojekt hat mal wieder einen Tiny85 
als Target. Also könnte ich das wohl schon morgen mal abchecken...

von dudinator (Gast)


Lesenswert?

Tom schrieb:
> Dabei ist mir aufgefallen,
> das der Timer1 anderst gestrickt ist als der Timer0 und sich auch
> anderst verhält, was ich mir nicht erklären kann.

https://www.duden.de/suchen/dudenonline/anderst

Außerdem wäre auch https://dassdas.de einen Blick wert, denke ich.

Sorry für OT.

von c-hater (Gast)


Lesenswert?

Tom schrieb:

> Ahhhhh.... Ich hatte gedacht, wenn ich nur den Vorteiler mit einem Wert
> aktiviere, das ich dann im synchronen Betriebsmodus bereits wäre.

Bist du auch. Solange du PCKE in PLLCSR nicht setzt, ist der Timer in 
der Systemtakt-Domäne.

von S. Landolt (Gast)


Lesenswert?

> Praktisch? Ehrlicherweise: Nein.

Genau - aber ich; wie sonst wäre ich zu der Aussage "3 scheinen zu 
reichen" gekommen.

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.