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?
Hängt wohl damit zusammen, dass Timer1 auch asynchron laufen kann. Einfach nach dem 'out TIFR' ein paar Takte warten, 3 scheinen zu reichen.
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...
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.
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 |
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...
Das schreiben meine zehn Finger automatisch, der Kopf ist daran nicht beteiligt ...
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 |
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...
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.
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?
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.
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...
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.
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.
> 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.