Hallo Leutz...
der Timer stimmt wirklich irgendwie nicht. Zumindest im µs Bereich.
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;
}
Laut dem Tool rnAVR sind die Werte für Prescaler und TCNT0 1 und 240.
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
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;
}
Da läuft die Uhr richtig.
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
Lesezeichen