PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Hilfe! Uhr läuft zu schnell?



HPM
26.02.2007, 18:41
Hallo Forumler,

habe eine (ich denke kleine) Frage!

Ich habe einen Mega8 dazu benutzt eine Funkuhr zu bauen.

Ich verwende die dcf.lib von:
copyright = W.Krueger
comment = DCF 77 Decoder
libversion = 1.00
date = 05.03.2006

mit dem Code:


'-------------------------------------------------------------------------------
' Allgemein Grundeinstellung
'-------------------------------------------------------------------------------
$regfile = "m8def.dat" 'Prozessor AT Mega8
$crystal = 4000000 '4MHz-Takt extern


'-------------------------------------------------------------------------------
' DCF-Funkuhr Grundeinstellung
'-------------------------------------------------------------------------------
$lib "dcf77.lib" ' einrichten für M8
$external Dcf77 ' und Eingangssignal!
Declare Sub Dcf77
Config Timer0 = Timer , Prescale = 1024 'Timer für 40Hz (25ms)
Const Startwert = 158
Timer0 = Startwert
On Timer0 Tim0_isr 'Überlauf alle 25ms
Enable Interrupts
Enable Timer0


Die Uhr läuft mit 4MHz tadellos!

Jetzt habe ich einen 16MHz Quarz eingesetzt
und den Code in:

$crystal = 16000000

geändert.

Problem: Meine Uhr läuft jetzt viel zu schnell!

Wo muss ich noch Änderungen vornehmen, um die Uhr in normaler Geschwindigkeit laufen zu lassen?

robocat
26.02.2007, 18:53
soweit ich das etz sehe zählt der timer mit startwert 158 also bis 97 quasi.
4MHz/1024(prescale)=3906,25Hz das geteilt durch 97 und du bist bei deinen 40,27Hz. wenn er jetzt 4 mal so schnell taktet, ergibt sich 161,1Hz, das sind etwa 6,2ms. (anstelle der 25ms)

wenn du den timer doppelt so lange laufen lässt (also mit startwert 61), solltest du anstelle der 25ms auf etwa 12,5ms kommen.

HPM
26.02.2007, 19:01
Hallo robocat ,

vielen Dank , erst mal für die schnelle Antwort!

Ich werden das Mal probieren!
Melde mich noch mal

HPM
27.02.2007, 12:16
Hallo robocat ,

hab Deine Berechnungen in die Programmierung übernommen und die Uhr ist langsamer gelaufen. Ich habe sie aber nicht auf 1Hz bekommen, ewta so 2Hz!

Ich hab dann statt den 16MHz Quarz einen 8MHz Quarz eingesteckt.
Jeztz läuft sie sekundengenau mit 8MHz!

Woran liegt denn das nun wieder ???

robocat
27.02.2007, 13:10
ich habe von bascom keinen schimmer, aber der a8 bleibt sich ja gleich.

timer0 ist ein 8 bit-timer, kann also maximal von 0 bis 255 zählen (256 schritte, errechenbar mit "2 hoch 8". der zähler startet hier aber nicht bei 0, sondern bei 61, zählt also nur 195 schritte.
ausserdem wird der Quarztakt noch durch den prescaler geteilt, prescale ist hier 1024. einen noch größeren prescaler hat der a8 nicht.

es ergibt sich also folgende frequenz:

quarztakt/(prescale-faktor*schrittzahl)=8000000/(1024*195)=40,06Hz

die dauer eines schrittes ist t=1/frequenz, also hier 0,02496 sekunden.
das sind halbwegs genau die 25ms, die du benötigst.

der langsamste takt mit 8-bit-timer bei 16 MHz wäre (etwa) 16,4ms. um auf 25ms zu kommen, müsstest du also den 16bit timer verwenden.

kurz gesagt ist die dauer eines schritts bei gleichem code bei halber frequenz logischerweise doppelt so lang.

kurz noch eine frage an die bascom-kundigen:
im datenblatt zählt timer0 von 0 bis zum compare-match. hier scheint das andersherum zu sein (zählt vom startwert bis 255), sonst würde meine rechnung ja nicht stimmen. ist das programmspezifisch oder eine eigenschaft von bascom?

wenn etwas nicht stimmt, korrigiert mich bitte.

gruesse von der katze

Dirk
28.02.2007, 20:45
Hallo HPM,

für den 16 MHz Quarz brauchst du den 16-Bit-Timer.

Da nimmst du dann z.B. Prescale = 256 und Timer-Startwert = 63974

Viel Erfolg!

Dirk

uwegw
28.02.2007, 21:13
kurz noch eine frage an die bascom-kundigen:
im datenblatt zählt timer0 von 0 bis zum compare-match. hier scheint das andersherum zu sein (zählt vom startwert bis 255), sonst würde meine rechnung ja nicht stimmen. ist das programmspezifisch oder eine eigenschaft von bascom?

Das liegt nicht an Bascom, sondern am Mega8. Sein timer0 hat nämlich keine compare-unit. Er kann nur ganz simpel vor sich hin zählen, bis er überläuft. Man muss daher im Overflow-interrupt das Zählregister mit dem passenden Wert laden, um eine bestimmte Periodendauer zu erhalten.

@HPM: wenn der Zählbereich von Timer0 bei 16Mhz nicht ausreicht, zähl doch einfach die Zeit nur in jedem zweiten Interrupt weiter... [der passende Startwert für 12,5ms wäre 61]