Guten Abend,
ich hätte da mal zwei Fragen ;-)
OCR erhöhen:
so: OCR1A=TCNT1+78;
oder so: OCR1A=OCR1A+78;
Ist das zweite evtl. schneller, weil OCR1A schon 'da' ist?
Außerdem würde ich gerne wissen, wie ich die Dinger am besten
initialisiere, bei mir läuft nämlich der 16er erstmal durch, bevor es
einen Match/Interrupt gibt, der dann das OCR erhöht. Das soll so nicht
sein
Momentan in der Reihenfolge:
Prescaler
Interrupt Mask
OCR=0
sei()
sollte es andersherum sein, also erst sei()?
danke!
> Ist das zweite evtl. schneller, weil OCR1A schon 'da' ist?
Nein, beide Register sind `volatile', d.h. sie werden immer
zugegriffen durch den Compiler.
Hallo Jörg,
wenn ich mal Zeit habe, mich direkt mit Assembler zu befassen, und dem,
was der Compiler ausspuckt, muß ich solche Fragen vielleicht irgendwann
nicht mehr stellen :-)
Dann spiele ich jetzt wohl mal mit der Reihenfolge der
Initialisierung..
>so: OCR1A=TCNT1+78;>oder so: OCR1A=OCR1A+78;
Das hängt davon ab was Du machen willst.
Willst Du OCR1A vom aktuellen Zählerstand um 78 erhöhen (TCNT1 !=
OCR1A gilt ja die längste zeit), oder willst Du einfach nur OCR1A um 78
erhöhen?
>...läuft nämlich der 16er erstmal durch...
Das mit dem durchlaufen ist ist im datenblatt beschrieben.
Falls beim setzen von OCR1A der inhalt von TCNT1 schon größer oder
gleich dem neuen wert von OCR1A ist läuft der zähler erst einmal bis
TOP==MAX durch. IMHO ist OCR=0 quatsch da ich nicht logisch
nachvollziehen kann was dann der MATCH-interrupt im CTC mode macht. Das
entspricht in etwa einer 0/0 (NULL geteilt durch NULL), und das ist (ich
hoffe ich erinnere mich erinnere richtig) undefiniert.
mein vorschlag:
TCNT=0;
OCR=NichtNullWert;
Interrupt Mask;
sei();
Prescaler; // == starten des zählers
In der initialisierung mach einfach:
OCR1A=TCNT1+78;
Im Interrupt mußt Du aber unbedingt:
OCR1A=OCR1A+78;
schreiben !
Es sei denn Du willst absichtlich den Interrupt total ungenau haben
(abhängig von anderen Interrupts und der Interrupteintrittszeit).
78 Zyklen ohne Vorteiler ist in C aber schon recht heftig, da könnte
Assembler nötig werden (nackter Interrupt ohne die Push/Pop-Arien).
Peter
Hallo Werner,
was verschlägt einen denn um 5 hierher?! staun
Da ich OCR in der ISR (Match A) erhöhe, spielt es keine Rolle, was ich
mache. Im Augenblick, in dem der Befehl ausgeführt wird, ist ja eben
TCNT==OCR. Also zumindest in meinem Fall, dem Normal Mode (Match und
der Zähler läuft weiter durch).
Aber ich weiß jetzt nicht ob der Zähler nicht noch eine Weile läuft,
bis dieser Befehl ausgeführt wird, deswegen mag das erste u.U.
günstiger sein. Tiefere Timer-Materie :-)
Ich hab's gestern auch noch zum Laufen bekommen, der Zähler muß
einfach als letztes (nach sei();) gestartet werden.
Danke.
Oh, guten Morgen Peter,
Vorteiler ist 256, deswegen hat der erste Zählerdurchlauf so lange
gebraucht, daß ich ewig nach einem nicht vorhandenen Fehler gesucht
habe..
> Es sei denn ..
Könntest Du das bitte noch ein bißchen erläutern, ich sehe den
Unterschied nicht.
Nun, der Timer läuft weiter, das OCR aber nicht.
D.h. beim Addieren auf den Timer kriegst Du also immer mehr Verspätung
mit rein.
Beim Vorteiler 256 könnte es gut gehen, wenn nicht andere Interrupts
mehr als 256 Zyklen benötigen.
Trotzdem würde ich ein "sicher sein" einem "könnte gut gehen" immer
vorziehen.
Worst-Case Szenario:
Uart-Interrupt wertet gerade ein Kommando aus, danach kommt im Main
eine Teil unter Interruptsperre, dann drängelt sich noch ein externer
Interrupt vor. Und das alles darf nun nicht mehr als 256 Zyklen dauern
inklusive bis zur Addition im Timerinterrupt.
Peter
Eine eigene Frage?
Dieser Thread ist über 21 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.