-
ATMEGA 16 TIMER-Problem
Hallo Leute,
ich habe mir einen Atmega 16 zugelegt und schon einiges programmiert. jz möchte ich mir eine Stopp uhr aus meinen 7-Segmenten basteln und da komme ich mit der Funktion _delay_ms() nicht mehr weiter. So hab ich auf mikrocontroller.net das Timer-Tutorial durch gearbeitet. Leider funtioniert mein Programm nicht, vielleicht könnt Ihr mir weiterhelfen!
Danke schon im vorhinein! :)
Hier ist mein Code:
Code:
#define F_CPU 1000000
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
int zaehler=0;
ISR (TIMER0_OVF_vect)
{
zaehler++;
}
int main()
{
//Timer konfigurieren
//Prescaler = 1024
TCCR0 = (1<<CS02)|(1<<CS00);
//Overflowinterrupt erlauben
TIMSK |= (1<<TOIE0);
//Aktivierung der Interrupts
sei();
//Ports konfigurieren
DDRB = 0xFF //PortB sind Ausgänge für LEDs
while(1)
{
if(zaehler==12)
{
PORTB = 0xF0;
}
}
return 0;
}
Das Problem ist das die LEDs sofort zu leuchten beginnen.
Wenn ich eine Frequenz von 1MHz habe und eine Prescaler von 1024
heißt dass das der Timer 976 mal erhöht wird pro sekunde=> darausfolgt das ich 976/256=3,81 Overflows habe.
Wenn ich die Variable zaehler dann bis 12 zählen lasse heißt, das das ich ungefähr 3sekunden warten muss bis die LEDs leuchten
MFG
fulltime
-
Was mir auffällt ist das du bei der Variable nicht volatile genommen hast. Du brauchst es aber damit die Variable ind der ISR gespeichert wird. Du musst also "volatile int zaehler=0;" schreiben. Ansonsten müsste ich im DB nachschauen.
MfG Hannes
-
Danke für die schnelle Antwort, doch leider ist sie nicht des Rätselslösung.
-
Hallo,
ich habe dein Programm mal auf meinem RN-Control ausprobiert und bei mir funktioniert es problemlos.
Ich hab das "unnütze" jetzt mal raus gemacht:
Code:
#include <avr/io.h>
#include <avr/interrupt.h>
volatile int Zaehler=0;
ISR (TIMER0_OVF_vect)
{
Zaehler++;
}
int main()
{
//Timer konfigurieren
TCCR0 = (1<<CS02)|(1<<CS00); //Prescaler = 1024
TIMSK |= (1<<TOIE0); //Overflowinterrupt erlauben
sei(); //Aktivierung der Interrupts
//Ports konfigurieren
DDRC = 0xFF; //PortB sind Ausgänge für LEDs
while(1)
{
if(Zaehler==12)
{
PORTC = 0x01;
}
}
}
Mein Mega32 läuft auf 1MHz (interner Oszilator) und nach etwa 3-4 Sekunden (geschätzt) geht die eine LED aus.
Also am Code liegt das Problem nicht :)
-
Ich habe jetzt statt PORTB PORTD verwendet aber es ist wieder das gleiche Problem. Könnte es sein, dass das Registers des Timers irgendwie defekt ist? Habe jetzt uach noch den 'Timer1 statt Timer0 verwendet, aber noch immer kein Erfolg
-
Bist du sicher das du 1MHz verwendest?
Auf was hast du den das Fusebit für den Takt am Mega16 stehen?
"#define F_CPU 1000000" ist nur eine Variable für die Software, welche die Taktgeschwindigkeit die du verwenden willst beinhaltet. Das stellt den Takt nicht auf 1MHz um. Das machst du nur mit den Fusebits :)
Deswegen kannst du in deinem Programm das #define F_CPU auch löschen, weil es macht in dem jetzigen Programm keinen Sinn und hat auch keine Funktion.
Eventuell hast du noch den 8MHz internen Oszillator aktiv und damit ist der Timer zu schnell für deine Berechnungen.
-
Nein ich verwende 1MHz das "#define F_CPU 1000000" braucht ich für den "_delay_ms()"-Befehl, denn damit liefert der delay-Befehl die richtige Zeitspanne. Sonst habe ich noch einen 12MHz Quarz doch denn verwende ich momentan nicht.
-
Hast du die Fuses kontrolliert? Funktionieren andere Programme (zum Testen kannst du den Ausgang togglen lassen)?
MfG Hannes
-
ja andere Programme funktionieren kann lauflichter, LEDs mit Taster an steuern, auf einer 7-Segment Anzeige rauf un runter zählen lassen. Das funktioniert einwandfrei. Nur der Timer geht nicht.
-
Also wie gesagt das Programm von mir läuft auf dem RN-Control und einem Mega32 problemlos und ich verwende den internen RC-Oszillator mit 1MHz.
Selbst dein Programm funktioniert so (hab nur PortB auf C geändert, weil da LEDs dran sind).