Timer0 stimmt nicht beim Atmega32
hallo zusammen,
ich bin am verzweifeln ich schaffe es nicht das der timer0 richtig funktioniert.
](*,)
der atmega lauft mit 16Mhz auf der rn control 1.4
es ist das erste mal das ich diesen timer brauche und hab deshalb auch keine erfahrung und versuch mir mit einem reinen timer programm die sache zu erklären
ich hätte gerne das er alle 10 ms zur probe eine LED ein/ausschaltet.
mein code
Code:
#include <avr/io.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/signal.h>
#include <string.h>
SIGNAL(SIG_OVERFLOW0){
static uint8_t count=0;
if (count == 156) {
count = 0; //zähler auf 0
if(bit_is_set(PORTC,7)) //PIN gesetzt ???
PORTC &= ~(1<<PC7);
else
PORTC |= (1<<PC7);
} else {
count++; // zahler erhöhen
}
TCNT0=0; //timer auf 0
}
int main (void){
TCCR0 |= (1 << CS00)|(1 << CS02); //prescaler 1024
TIMSK |= (1 << TOIE0); // Overflow Interrupt aktivieren
sei();
for(;;){
//mach was
}
}
bei 16 Mhz müsste der timer alle 64µs überlaufen?
wenn ja dann muss er 156 mal überlaufen um die led einmal ein und aus zu schalten? das wären dann alle 10 ms
ich weiß leider nicht ob das so stimmt?
besten dank!
servusssss
ps.: ich hab leider nicht im forum suchen könne falls es schon eine eintrag über dieses problem gibt.
Da hab ich auch mal was dazu zu sagen
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