Hallo Leute, ich möchte folgendes lösen: Prozessor: 8051 Takt 11059200Hz Serielle über T0 8 Bit autoreload Timer erzeugt 1/100 sec. Signal für eine akurate manuelle reload Rpoutine hab ich mir gedacht den reload Wert auf die nach Überlauf hochgezählten TL1-TH1 auf zu adieren. Ist folgendes korrekt? M_1A: clr TF1 push acc push psw clr TR1 ;timer stoppen mov a,TL1 ;1Zyk add a,#000h+7 ;1Zyk TL1 reload(00)+routinenzykl.zahl dazu mov TL1,a ;1Zyk und tl speichern mov a,TH1 ;1Zyk addc a,#0DCh ;1Zyk reloadwert auf die ; drübergelaufenen dazuadieren mov TH1,a ;1Zyk #0DCh= software reload wert TH1 setb TR1 ;1Zyk pop psw pop acc Gruß Andi
Moin, ist nahezu korrekt, aber... Das Löschen von TF1 kannst Du Dir sparen, das passiert beim RETI am Ende sowieso, verschenkt nur Zyklen. Außerdem solltest Du besser den Timer nicht anhalten, dadurch verlierst Du einige Maschinentakte beim Zählen. Ich würde das Ganze so schreiben: TL1REL .equ 0h TH1REL .equ 0DCh ; Möglicherweise mußt Du TL1REL noch anpassen (auf ; 2 setzen oder so), weil bei der Addition und dem ; Zurückschreiben noch ein paar Zyklen vergehen. ; Ich habe gerade keine Lust, die Zeiten für die ; Befehle nachzuschlagen... ;-) ; interrupt routine für timer1 beginnt hier: M_1A: push acc push psw mov a,#TL1REL add a,TL1 mov TL1,a ; mov TH1,#TH1REL ; Den Wert kannst Du ohne Addition reloaden, weil er ; ZWINGEND auf 0 sein muss (wir haben ja die ; Interruptroutine gerade eben erst aufgerufen!) pop psw pop acc reti ; nicht vergessen!! Gruß, Wolfgang
Wolfgang wrote: > Das Löschen von TF1 kannst Du Dir sparen, das passiert beim RETI am Ende > sowieso, verschenkt nur Zyklen. Nein, es passiert schon beim Interrupteintritt. > Außerdem solltest Du besser den Timer > nicht anhalten, dadurch verlierst Du einige Maschinentakte beim Zählen. Das Anhalten sollte man unbedingt machen, sonst kann es zu Überläufen kommen während des Reloads. Man kann ja nicht beide Bytes gleichzeitig laden. > mov TH1,#TH1REL ; Den Wert kannst Du ohne Addition reloaden, weil er > ; ZWINGEND auf 0 sein muss (wir haben ja die > ; Interruptroutine gerade eben erst aufgerufen!) Und wenn man noch andere Interrupts hat ? Die Additionsmethode mit Anhalten ist schon völlig richtig und sicher, unabhängig vom Reloadwert und anderen Interrupts. Man sollte sich nicht unnötig potentielle Fehlerquellen einbauen für wenige Zyklen Einsparung. http://home.tiscali.de/peterd/appl/soft/clock/index.htm Peter
Zunächstmal.. ich hatte gar nicht gedacht die routine in einem interrupt arbeiten zu lassen. Es währe sicher die einfachste Methode aber sie könnte mir bei den darübergelagerten Routinen dazwischenfunken. Diese sind schon so programmiert,daß sie nicht auf irgend etwas warten und kurz genug sind damit der timer nicht 2mal überläüft. Es geht darum einen 8051 eine genaue Baudrate UND eine genaue Zeit beizubringen.(sicher,beim 8052 no problemo,da 16bit autoreload) da fand ich bei einem 10.059200 quarz den nachladenwert dc00H sehr interessant. befindet sich die isr alleinig in high prirorität so wird der timer tl0 doch normal nicht 2 mal überlaufen. Es würde hier reichen den Th0 mit dc zu speisen. der tl0 nachladewert ist ja ohnehin 00. Allerdings sind aus meinen Erfahrungen und auch Peters(11.059008Mhz) dei theorie und praxis weit entfernt. Desswegen die adition. Peter: wieso gehen zyklen verloren? der timer zählt weiter und dann wird doch der reload addiert und nicht gemovt. erst wenn die addition ein überlauf erzeugt,fällt das Kind in den Brunnen. Sicher, es gibt lange und kurze Perioden,aber die gleichen sich normal aus. Wolfgang, ich habe die verlorenen Zyklen(timerstop) mit add a,#000h + 7 berücksichtig. Ich wollte nur mal von euch wissen ob die Kalkulation passt. Ich weiß nicht ob intern erst gestoppt und oder erst noch der timer nen takt kriegt und dann erst stoppt. und ob sich das wohl beim Starten egalisiert. Auf mein posting dahin hat niemand reagiert. Ich konnte auch nix im web finden. muß jetzt arbeiten schöne Grüße Andi
Andreas Krieger wrote: > ich hatte gar nicht gedacht die routine in einem interrupt > arbeiten zu lassen. > Es währe sicher die einfachste Methode aber sie könnte mir > bei den darübergelagerten Routinen dazwischenfunken. Dann weißt Du einfach verschiedene Prioritäten zu, die höhere dem eiligeren Interrupthandler. > wieso gehen zyklen verloren? Hab ich nirgends gesagt. > Ich weiß nicht ob intern erst gestoppt und oder > erst noch der timer nen takt kriegt und dann erst stoppt. > und ob sich das wohl beim Starten egalisiert. Das ist doch egal, Hauptsache das Starten und Stoppen erfolgt gleich (vor oder nach dem Zählen). Peter
Hallo nochmal. >> wieso gehen zyklen verloren? >Hab ich nirgends gesagt. stimmt. war ein Mißverständnis. Deine Antwort bezog sich auf das Löschen von TF0 und nicht auf die verlorenen Zyklen. >> ich hatte gar nicht gedacht die routine in einem interrupt >> arbeiten zu lassen. >> Es währe sicher die einfachste Methode aber sie könnte mir >> bei den darübergelagerten Routinen dazwischenfunken. >Dann weißt Du einfach verschiedene Prioritäten zu, die höhere dem >eiligeren Interrupthandler. Nun ja,Das Hauptprogramm sollte an gewissen stellen nicht unterbrochen werden weil ich sonst die Zeitflags nochmal zwischenspeichern müßte. Ich muß das nochmal genau Simulieren und oder Gedanklich durchgehen. Sollte es egal sein,dann werd ich das sicher in eine isr packen. So. und nochmal zu Wolfgang: > mov TH1,#TH1REL ; Den Wert kannst Du ohne Addition reloaden, weil er > ; ZWINGEND auf 0 sein muss (wir haben ja die > ; Interruptroutine gerade eben erst aufgerufen!) Wenn der Timer nach setzten des TF flags zu Beginn einer isr routine garantiert 0 wäre,würde ich so einen Aufwand nicht betreiben. Es gibt aber auch 2Zyklen und 4 Zyklen Befehle. Diese werden erst noch abgearbeitet. Also kann es passieren das bis zu 3 zyklen verloren gehen. Ich schrieb von einer akuraten Methode,eine,bei der es genau stimmt. alles klaro? ;-)
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.