Forum: Mikrocontroller und Digitale Elektronik wie add-funktion mit timer-counter TCNT0 benutzen?


von fksystems (Gast)


Lesenswert?

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?

von crazy horse (Gast)


Lesenswert?

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
.
.

von leo9 (Gast)


Lesenswert?

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

von Khani (Gast)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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

von leo9 (Gast)


Lesenswert?

@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

von fksystems (Gast)


Lesenswert?

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?

von HanneS (Gast)


Lesenswert?

Schick doch den 1200er in der (Nixtu-) Hauptschleife in den SLEEP-Modus,
dann findet der Interrupt immer die gleichen Bedingungen vor...

Bit- & Bytebruch...
...HanneS...

von fksystems (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.