Hallo Leutz...
der Timer stimmt wirklich irgendwie nicht. Zumindest im µs Bereich.
Laut dem Tool rnAVR sind die Werte für Prescaler und TCNT0 1 und 240.Code://Für ATMega32 mit 16MHz #include <avr/io.h> #include <avr/interrupt.h> volatile uint16_t ui16_msecs; volatile uint16_t ms = 0; void Clock(); ISR(TIMER0_OVF_vect) { TCNT0 = 240; ui16_msecs++; if( ui16_msecs >= 1000L ) // eine Millisekunde vergangen { ui16_msecs = 0; ms++; } } void initTimer() { TCCR0 = (1<<CS00); // Prescaler 1 TCNT0 = 240; /* TOIE0 Overflow Interrupt */ TIMSK |= (1<<TOIE0); sei(); /* Interrupt global einschalten */ } void Clock() { static uint8_t s = 0; static uint8_t m = 0; static uint8_t h = 0; if( ms > 999 ) { ms -= 1000; s++; } if( s > 59 ) { s = 0; m++; } if( m > 59 ) { m = 0; h++; } if( h > 23 ) h = 0; // Ausgabe, wie auch immer von h,m,s und ms } int main(void) { initTimer(); while(1) { Clock(); } return 0; }
Problem: Die Uhr läuft viel zu langsam! Geschätzt 3-4mal zu langsam.
Anders sieht es aus, wenn man keine µs will sondern eine ms!
rnAVR sagt Prescaler = 64, TCNT0 = 6
Da läuft die Uhr richtig.Code://Für ATMega32 mit 16MHz #include <avr/io.h> #include <avr/interrupt.h> volatile uint16_t ms = 0; void Clock(); ISR(TIMER0_OVF_vect) { TCNT0 = 6; ms++; } void initTimer() { TCCR0 = (1<<CS01)|(1<<CS00); // Prescaler 64 TCNT0 = 6; /* TOIE0 Overflow Interrupt */ TIMSK |= (1<<TOIE0); sei(); /* Interrupt global einschalten */ } void Clock() { static uint8_t s = 0; static uint8_t m = 0; static uint8_t h = 0; if( ms > 999 ) { ms -= 1000; s++; } if( s > 59 ) { s = 0; m++; } if( m > 59 ) { m = 0; h++; } if( h > 23 ) h = 0; // Ausgabe, wie auch immer von h,m,s und ms } int main(void) { initTimer(); while(1) { Clock(); } return 0; }
Warum?
Wieso?
Weshalb?
Testet bitte die Codes, nicht damit ich wirklich einen fatalen Denkfehler habe (Ganz vollständig ist der Code u.U. nicht, da er hier editiert wurde, es geht hauptsächlich um die Presclaer/TCNT0-Werte).
thx4answer
Banzai







Zitieren

Lesezeichen