Forum: Mikrocontroller und Digitale Elektronik manueller 16 bit reload


von Andreas K. (oldcoolman)


Lesenswert?

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

von Wolfgang (Gast)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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

von Andreas K. (oldcoolman)


Lesenswert?

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














von Peter D. (peda)


Lesenswert?

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

von Andreas K. (oldcoolman)


Lesenswert?

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