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