ich wollte auf den TCNT0-wert (timer/counter upcounter register-wert) eine zahl aufaddieren (benutze at90s1200 und attiny11 mit assembler), damit sich der durchlauf des timers verkürzt. jetzt kann ich das scheinbar nicht machen. der befehl add TCNT0, r16 scheint nicht zu funktionieren. weiß jemand, welchen befehl ich stattdessen benutzen kann? oder ist da ein addieren, ohne den wert vorher in ein anderes register einzulesen, nicht möglich bei dem wert?
geht nur, wenn du das TCNT-Register liest, dann veränderst, anschliessend wieder zurückschreibst. Üblicherweise wird allerdings ein fester Wert verwendet, am Anfang der Timer-ISR steht es dann in etwa so: in r1, sreg ldi r16, reload out TCNT0, r16 . .
hallo crazy, deine Variante mag üblich sein hat aber den nachteil dass die Zeit zwischen Überlauf und reload setzen nicht konstant ist (Latenzzeit der Interrupt Auslösung). Mit der Addition wird dieser Fehler aber ausgeglichen. grüsse leo9
Hallo Leo, und wie würde man das Deiner Meinung nach realisieren ? Außerdem, man kann bei der Interrupt-Latenzzeit schon Aussagen über deren Zeitverhalten machen. Eine bessere Lösung wäre dann höchstens noch ein free-running-counter mit compare-match. Dann werden die Interrupts zu präzisen Zeitpunkten ausgelöst und man kann den nächsten Compare-match Zeitpunkt setzen. Aber wer will so viel Genauigkeit, dass die Interrupt-latency überhaupt eine Rolle spielt ? MfG, Khani
Das Addieren kostet gerade mal einen Takt mehr. Deshalb ist bei mir das Addieren immer "üblich", auch wenn es mal nicht so genau sein muß. Da während der Addition der Timer weiterläuft, muß man 2 Takte weniger addieren: in r16, TCNT0 subi r16, -(reload - 2) out TCNT0, r16 Mit Vorteiler ist es aber nicht mehr genau, da man ja nicht weiß, ob der Vorteiler gerade bei der Addition überläuft oder nicht. Peter
@khani: die Addition hat Peter bereits gezeigt. Die Latenzzeit ist nicht vorhersagbar, da der Interrupt während eines 1- oder 2-Zyklen Befehls auftreten kann und der Befehl auf jeden Fall abgearbeitet wird. Ein Timerinterrupt ist zwar "systemsynchron", damit ist der Fehler max. + ein Taktzyklus. Bei asynchronen externen Interrupts ist der Fehler aber bereits im Bereich +null bis +zwei Taktzyklen und das kann schon relevant werden. Die einzige Möglichkeit den Fehler zu verkleinern ist ein Stromsparmodus bei dem der uP nur "nopt" und vom Int. wieder geweckt wird (es wird immer ein einzyklischer Befehl beendet und dann der int. abgearbeitet). grüsse leo9
ok, es klappt jetzt. es geht jetzt mit der ddition, die mehrere befehle benötigt. stimmt. ich habe nur interrupts als befehle laufen. wärend der restlichen zeit passiert nix. es wird wärend der restlichen zeit immer nur eine schleife durchlaufen. ich benutze als auslösewert für den timer ck8 . ich habe die stelle so mit NOP-befehlen verschoben, daß sichergestellt ist, daß wärend der addierung keine veränderung des timer-wertes auftritt. so war es jedenfalls in der simulation. jetzt ist die frage: kann es denn jetzt trotzdem passieren, daß in einem zustand, den ich nicht simuliert habe, trotzdem der interrupt so unglücklich aufgerufen wird, daß plötzlich der wert sich wärend der addition verändert? also ich habe mir darauf die frage so beantwortet, nachdem ich eure antworten gelesen habe: ich muß überlegen, welche taktlänge zwischen der minimalen und der maximalen taktlänge der benutzten befehle liegen kann. und diese anzahl an taktzyklen kann sich der erhöhungszeitpunkt maximal verschieben. d.h, wenn ich auch wärend der restlichen zeit, wo keine interrupts sind, den controller etwas arbeiten lasse, muß ich gucken, wieviele takte mein größter befehl lang ist. davon ziehe ich eins ab. dann mache ich das wieder so, daß in der simulation der timer-wert gerade eben umgesprungen ist, bevor die addition gestartet wird. zu dieser version addiere ich aber noch die anzahl der NOPs hinzu, die zwischen der minimalen und maximalen befehlslänge der verwendeten befehle liegen. d.h., wenn alles geht, und ich einen maximal 4-takt langen befehl habe, füge ich noch 3 zusätzliche NOPs ein. frage jetzt: ist das richtig so oder sind noch wo denkfehler drin oder habe ich noch was nicht berücksichtigt? aber wenn ich, wärend keine interrupts ausgeführt werden, nur die loop-schleife laufen habe, ist doch sicher garantiert, daß er immer nach der selben stelle in den interrupt springt oder kann bei einer loop-schleife auch dieser fehler-effekt auftreten, daß er nicht immer nach der selben zeit von takten in den interrupt springt?
Schick doch den 1200er in der (Nixtu-) Hauptschleife in den SLEEP-Modus, dann findet der Interrupt immer die gleichen Bedingungen vor... Bit- & Bytebruch... ...HanneS...
update: warte mal: loop-schleife hat ja doch 2 take. d.h. also, ich müßte bei nicht sleep-befehl ein noop zuästzlich einfügen. aber da ich ehe den sleep-befehl benutze, müßte es egal sein.
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.