Hallo,
ich habe mich auch mal an das Projekt DCF77 gewagt.
Bis die Zeit Synchronisiert wird lasse ich sie via Interrupt hoch
zählen.
Dazu habe ich mir eine kleine Timerklasse geschrieben, die mir dabei
helfen soll.
Jetzt habe ich allerdings bemerkt, dass meine Uhr ca. 2 Sekunden pro
Minute zu langsam läuft und ich habe noch keine Idee warum.
Mein uC läuft mit 16MHz.
Timer2, der den 1ms-Interrupt erzeugt:
1 | //1ms Interrupt
|
2 | TCNT2 = 0;
|
3 | OCR2A = (250 - 1); // so gibt das 1ms - Pulse
|
4 | TCCR2A = 0; //Pins nicht verbunden, aber Clear Timer on Compare match (CTC) mode
|
5 | TCCR2B = ( 1 << CS22); //Prescaler 64
|
6 | TIMSK2 = ( 1 << OCIE2A); //Timer/Counter2, Output Compare A Match Interrupt Enable
|
Interrupt-Routine:
1 | ISR( TIMER2_COMPA_vect)
|
2 | {
|
3 | GetTimerHelper().Interrupt1ms();
|
4 | }
|
main:
1 | while(1)
|
2 | {
|
3 | GetTimerHelper().Process();
|
4 | }
|
Wrapper für die globale Variable
1 | CTimerHelper& GetTimerHelper()
|
2 | {
|
3 | static CTimerHelper TimerHelper;
|
4 | return TimerHelper;
|
5 | }
|
Inhalt Interruptroutine
1 | void CTimerHelper::Interrupt1ms()
|
2 | {
|
3 | #if TIMER_SUPPORT_1MS
|
4 | do1ms++;
|
5 | #endif
|
6 |
|
7 | ms++;
|
8 |
|
9 | if( ms % 10 == 0) do10ms++;
|
10 | #if TIMER_SUPPORT_100MS
|
11 | if( ms % 100 == 0) do100ms++;
|
12 | #endif
|
13 | if( ms >= 1000) {
|
14 | do1s++;
|
15 | ms = 0;
|
16 | }
|
17 | }
|
Hat jemand eine Idee, wo ich schauen könnte?
Wenn ihr den Code kurz testen wollt geht das ganz einfach:
1 | class ctest : CTimer
|
2 | {
|
3 | //hier eigenen code rein
|
4 | void Timer1s(){}
|
5 | void Timer10ms(){}
|
6 | void Timer100ms(){}
|
7 | } test;
|
ggf müsst ihr noch diesen codeschnipsel vorher einfügen, dass alles
klappt:
1 | extern "C" {
|
2 | void __cxa_pure_virtual()
|
3 | {
|
4 | uart_puts_P( "ERROR!\n\r-->__cxa_pure_virtual\n\r");
|
5 | // put error handling here
|
6 | }
|
7 | }
|
Auch wenn der Funktionsansprung etwas dauern sollte, der Timer2 läuft
doch außerhalb des Programms weiter. D.h. die Zeit die dadurch verlohren
wird sollte sich nicht auswirken, da der Interrupt dann einfach früher
kommt.
Habt ihr eine Idee? Danke schon mal!