PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Wie genau ist der Timer1 bei ATMEGA16



Arne
14.12.2004, 15:45
Hi,

wie genau ist der Timer1 des ATMEGA16?
Ich habe mit Hilfe von rnAVR und zum Teil geklauten :-) Code eine Uhr geschrieben. Diese Uhr lief die 1. Stunde vor und jetzt nach (je ca 20 Sek). Ist das normal oder mein Code so schlecht (bin Anfänger)?


Cls
Config Lcdpin = Pin , Db4 = Porta.3 , Db5 = Porta.2 , Db6 = Porta.1 , Db7 = Porta.0 , E = Porta.4 , Rs = Porta.5
Config Lcd = 16 * 2


Dim Sekunde As Byte
Dim Minute As Byte
Dim Stunde As Byte


Config Timer1 = Timer , Prescale = 256
On Timer1 Timer_irq
Const Timervorgabe = 3036

Enable Timer1
Enable Interrupts


Stunde = 16 'Uhr stellen
Minute = 27


Do
'Hier könnte Ihr Hauptprogramm stehen
Loop



'Dies ist der Programmteil, der in dem von ihnen gewählten
'Intervall aufgerufen wird
Timer_irq:
'Timer1 = Timervorgabe

Sekunde = Sekunde + 1
If Sekunde = 60 Then
Sekunde = 0
Minute = Minute + 1
If Minute = 60 Then
Minute = 0
Stunde = Stunde + 1
If Stunde = 24 Then Stunde = 0
End If
End If
Cls
Lcd Stunde ; ":" ; Minute ; ":" ; Sekunde
Return



P.S.: Ich benutze ein 16MHz Quartz

AlexAtRobo
14.12.2004, 20:40
Hallo,

da gibt es 2 Probleme. Erstens läuft z.B das Quarz nicht genau mir der Frequenz die draufsteht, sondern eben in einem Gewissen Toleranzbereich.

Zweitens hast du immer einen Rundungsfehler. Ein 4MHz Takt lässt sich nicht sauber auf 1 Hundertstel etc. Teilen läßt. Die paar Takte die Verlorengehen, muß man also hier und da wieder dazuzählen.
Einfacher und genauer wird es wenn du einen Uhrenquarz verwendest.

lg

Alex

Frank
15.12.2004, 00:09
Hi AlexAtRobo,
er hat doch 16 Mhz, hast du glaube übersehen.
Also mit 16 Mhz Quarz bekommt man das eigentlich rechnerisch genau hin, aber wie du schon sagst - es gibt Toleranzen.
10 Sekunden pro Stunde kommen mir allerdings etwas viel vor, aber vielleicht ist es so.

Ich erinnere mich das in Amateuerfunkbüchern, bei Quarzoszillatoren, mit einem Drehkondensator die Quarzfrequenz manchmal ein wenig verschoben wurde um die Tolereranz auszugleichen. Aber ob das hier geht - das ist nicht mein Spezialgebiet, vielleicht kann da ein HF-Experte was zu sagen.

AlexAtRobo
15.12.2004, 09:11
Ok, hab ich übersehen.
Du stellst den Timer auf 256/Teiler ein. Das bedeutet, der Timer wird 62500x pro Sekunde erhöht. Dann lädst du nur 1x die Timervorgabe, die andere Zeile ist ausgesternt. Wie auch immer, als wenn du 3036 vorlädst, dann wird von dort weg erhöht.
65535-3036 = 62499. Die 3036 muss immer vorgeladen werden.
1/16000000*256*3036 = 0,048 sec.

Vielleicht hilft dir das ja.
Über die Änderung der 3036 kannst du theoretisch eine Korrektur vornehmen.
lg
Alex

Frank
15.12.2004, 11:06
Stimmt natürlich, das die Zeile auskommentiert ist

'Timer1 = Timervorgabe

hab ich jetzt auch erst gesehn. Es sollte aber reichen die Auskomentierung wegzulassen, dann hat man bereits höchste Genauigkeit.

Genauer gehts nicht mehr - siehe RN-AVR-Berechnung:
https://www.roboternetz.de/phpBB2/dload.php?action=file&file_id=169

Bei deiner Berechnung AlexAtRobo stimmt irgendwas nicht - check das nochmal.

AlexAtRobo
15.12.2004, 11:17
Hallo Frank,

Hm, kann ich jetzt nicht sehen, aber ich denk nochmal laut:
Takt: 16 000 000 Mhz.
Bei 256 Vorteiler -> 16 000 000 / 256 = 62500 Erhöhungen.

Wir wollen, das der Timer 1x pro sec. überläuft.
Also muss er 65535 - 62500 = 3036 vorgeladen bekommen.
sonst "verliert" man 0,048sec pro sekunde, oder?
1/f = 1/16000000 = 62,5ns für 1 Takt. * 256 (ist der Vorteiler) = 16us * 3036 (Der ausgesternte Wert) = 0,048

wo liegt der Fehler?

lg

Alex

RCO
15.12.2004, 11:27
Der Timer muss mit 3036 vorgeladen werden. Wenn er überläuft, wird die Interruptroutine gestartet. Der Timer muss dann natürlich neu beladen werden, da er sonst den wert 0 hat! Das dürfte klar sein. In deinem Code steht unten in der Routine:


'Timer1 = Timervorgabe

Das ' verhindert das die Anweisung ausgeführt und der Timer neu beladen wird, deshalb entsteht jede Sekunde ein Fehler von 0,048sec! Es müsste rein rechnerisch ein Fehler von 172,8 sec pro Stunde entstehen.

MFg Moritz

AlexAtRobo
15.12.2004, 12:40
Übrigens stellt sich die Frage, was der Compiler draus macht.
Theoretisch muss man ja noch die paar Takte korrigieren (Habe ich oben angesprochen), die vergehen, bis der Timer nachgeladen ist - oder läuft der Prescaler weiter und setzt sich nicht zurück?

lg
Alex

RCO
15.12.2004, 12:44
Der Prescaler läuft weiter, aber das spielt ja keine Rolle.
Ja man müsste Wissen, wieviel takte genau vergehen, bis der Timer nachgeladen ist, denn schließlich läuft er erst über, dann geht er zur Routine und lädt dann nach, aber um ds zu korrigieren müsste man vermutlich einen kleineren Prescaler verwenden, denn es wird, denke ich, keine 256 Takte ausmachen.

MFg Moritz

AlexAtRobo
15.12.2004, 12:49
Ja, in dem Fall geb ich dir recht. Ich war mir jetzt nur nicht sicher, ob der Precaler beim Vorladen ebenfalls resettet wird. Also wird der Fehler wohl wirklich aus den Quarztolleranzen kommen.
lg
Alex

RCO
15.12.2004, 12:52
Wenn du es genau haben willst, dann nim einem DCF-empfänger, du musst ja nciht zwangsläufig die mitgesendeten Datus-Daten etc. empfangen, sonder nur den Impuls über einen Interrupteingang, dann brauchst du nciht mal nen Timer.

MFg Moritz

fzehner
15.12.2004, 13:23
Bei einem DCF-Empfänger würde er nur jede Minute eine Sekunde verlieren, da nur 59 Signale gesendet werden. Auf der sicheren Seite ist man erst, wenn man das Signal auch auswertet, da man nie sagen kann, wie gut das Signal ankommt. Bei einem schlechten Empfang kann es zu Spitzen kommen, die ausreichen um einen Interrupt auszulösen.

Frank

15.12.2004, 15:06
Hallo,

habe Moritzs Rat 0(Danke @ Moritz) befolgt. Scheint zu funktionieren. Ich melde mich nach 24 Stunden erneut.

Arne