mikrocontroller.net

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


Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich programmiere den AT90s8515 in ASM.

Autor: Jadeclaw (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Läubi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
genial!! funktioniert

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.