Forum: Mikrocontroller und Digitale Elektronik Timer soll jede Minute Register inkrementieren


von Bernd (Gast)


Lesenswert?

Servus..

Ich möchte mir einen Datenlogger bauen, der wenn ein entsprechendes
Ereignis eintritt (PortA1=High), die dazugehörige Zeit mitspeichern.
Und zwar reichen dort die bis dahin abgelaufenden Minuten. Diese müssen
ebend unabhängig vom Rest des Programms in einem Extra Register r19
aufaddiert werden. Man kann dann später die Uhrzeit zurückrechnen, wenn
man die Anfangszeit kennt.
Mir fehlt halt ein Programmschnipsel, wie man einen Timer dazu bringt -
wahrscheinl. per Interrupt - ein Register "Minuten" jede Minute um 1
zu erhöhen...

von Bernd (Gast)


Lesenswert?

Ich programmiere den AT90s8515 in ASM.

von Jadeclaw (Gast)


Lesenswert?

Das 'Uhrwerk' einer Uhr. (AT90s1200)
Zählt nach dem Einschalten ab 00:00:00 hoch.
Der Quarz mit 3.2768MHz wird hier über Vorteiler 1024
und Timer0 (0x80) auf 25 Interrupts pro Sekunde heruntergeteilt.
Diese werden über die Variable 'Puls' abgezählt.
Ist Puls=0, wird die Sekunde erhöht.
Die beiden mit (X) markierten Zeilen sind bei
anderem Quarz/Teileränderung anzupassen.
Die Zeit steht als gepackte BCD-Zahl in Stunde, Minute, Sekunde zur
Verfügung.


.def Temp = R16
.def Display = R17
.def Timer = R18
.def Puls = R19
.def Sekunde = R20
.def Minute = R21
.def Stunde = R22

RESET:                  ;Reset Label
  clr Sekunde
  clr Minute
  clr Stunde
  ldi Temp, 0x05      ;Timer0-Mode auf Vorteiler 1024
  out TCCR0, Temp
  ldi Timer, 0x80      ;Timer0 auf überlauf 25Hz.
  out TCNT0, Timer
  ldi Temp, 0x02  ;Timer0-Int. freigeben ( Für 90s8515 anpassen,
        ;TOIE0 muss aktiv sein)
  out TIMSK, Temp
  in Temp, SREG      ;Interrupts generell freigeben
  ori Temp, 0x80
  out SREG, Temp
  ldi Puls, 25      ;Timer0-Überlauf runterteilen (X)

TIMER0:            ;Timer0-Einsprung.
  out TCNT0, Timer    ;Timer0 neu starten
  dec Puls        ;Überlauf-Teiler -1
  cpi Puls,0        ;Null?
  brne Not_Null      ;Nein?, Dann raus.

  ldi Puls, 25      ;Ja? Überlaufteiler setzen (X)
  inc Sekunde        ;Sekunde +1
  mov Temp, Sekunde
  andi Temp, 0x0f      ;Oberes Nibble weg
  cpi Temp, 0x0a      ;Gösser 9?
  brne Not_Null      ;Nein? Dann raus
  swap Sekunde      ;Nibbles tauschen
  andi Sekunde, 0x0f    ;Unerwünschtes Nibble weg
  inc Sekunde        ;Sekundenzehner +1
  swap Sekunde      ;Nibbles tauschen
  cpi Sekunde, 0x60    ;Grösser 59?
  BRNE Not_Null      ;Nein? Dann raus

  clr Sekunde        ;Ja? Sekunden auf null
  inc Minute        ;Ab hier, wie Sekunden
  mov Temp, Minute
  andi Temp, 0x0f
  cpi Temp, 0x0a
  brne Not_Null
  swap Minute
  andi Minute, 0x0f
  inc Minute
  swap Minute
  cpi Minute, 0x60    ;Minute grösser 59
  BRNE Not_Null      ;Nein? Dann raus

  ldi Minute, 0      ;Ja? Minuten auf null.
  inc Stunde        ;Ab hier wie Sekunde
  mov Temp, Stunde
  andi Temp, 0x0f
  cpi Temp, 0x0a
  brne Not_Null2
  swap Stunde
  andi Stunde, 0x0f
  inc Stunde
  swap Stunde

Not_Null2:
  cpi Stunde, 0x24    ;Stunde grösser 23
  BRLO Not_Null      ;Nein? Dann raus
  clr Sekunde        ;Ja? Alles auf null
  clr Minute
  clr Stunde

Not_Null:
  reti

Hoffe, das hilft.

Gruss
Jadeclaw.

von Läubi (Gast)


Lesenswert?

Also im Prinzip machast du das so:

Timer aktivieren, und am besten im Overflow Modus betreiben.
sagen wir mal du benuzt den 16bit timer, dann ist die größte
speicherbare Zahl: 2^16 = 65536
Wenn du jezt 1hmz nimmst und du hast meist folgende Prescaller zur
verfügung:
/0
/8
/64
/256
/1024
(Steht im Datenblatt im Abschnitt zu dem Counter)

Jezt rechnest du immer
1.000.000 / 8 = wären z.b 125.000 das teilst du durch den Maximalwert
deines Timers (65536 bei 16bit) wären dann 1,9073486328125 also etwa 2
Overflows / Sekunde. Da jede Minute 60 sekunden hat, hast du also das
ganze noch mal 60 = 114,44091796875

Nun aktivierst du den Overflow Interupt und zählst dort bei jedem mal
ein register um eins hoch, wenn du bei 114 angekommen bist löscht du
das register und zählst deine Minute um einen hoch. Fertig! :)

Das ganze ist nicht mit einer Atomzeit vergleichbar, da das ganze
natürlich etwas vor geht, aber wenn man die Quarzfrequenz gut wählt und
mit dem Vorteiler rumspielt kommt man ab udn an auch auf glatte Werte
die durchaus brauchbar sind.
Im Obigem Beispiel wird deine Zeit also immer die abweichung von 0,44
haben aber das kann man im Prinzip auch ausgelichen es gibt in der
COdesammlung dazu ein Programm wie man eine genaue Sekunde definiert,
da kannst du dir was abschauen, aber je nachdem wie genau du das
brauchst wird es auch so gehen.
Da du aber eh nur Minuten genau messen willst solte das schon
funktiinieren, ich hab das auf diese Art mal für nen Countdown gemacht
und mit ner ordinären Küchentimer verglichen war eigentlich sehr
Syncron, und wenn du eine etwas krumme Quarzfrequenz wählst läßt sich
das ganze auch meist ganzzahlig lösen.

von Bernd (Gast)


Lesenswert?

genial!! funktioniert

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.