PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Probleme mit Timer und ATMega 32



steffen21m
07.01.2008, 05:19
Hallo Leute !
Habe ein kleines Uhrenprogramm. Wenn der Timer1 des Atmega32 einen Overflow hat soll eine Sekunde dazugezählt werden. Leider arbeitet der ATMega aber nicht das Interruptprogramm ab. Was mache ich falsch ??
(Programm siehe unten ;-)) In meiner Main wird Start_Clock() aufgerufen. Timer läuft auch .. nur die ISR wird nicht abgearbeitet.


Gruß Steffen


#include "clock.h"

//Die Uhrzeit steht in folgenden Variablen
unsigned char ss=0; //Globale Variable für die Sekunden
unsigned char mm=12; //Globale Variable für die Minuten
unsigned char hh=12; //Globale Variable für die Stunden
unsigned char day=12; //Globale Variable für den Tag
unsigned char mon=12; //Globale Variable für den Monat
unsigned int year=2007; //Globale Variable für das Jahr


//################################################## ##########################
//Overflow Interrupt wird bei 59 Sekunden ausgelöst
ISR(TIMER1_OVF_vect)
//################################################## ##########################
{

//Zurücksetzen des Timers
TCNT1 = 65535 - (SYSCLK / 1024);
//1 Sekunde addieren
Add_one_Second ();

}


//################################################## ##########################
//Addiert 1 Sekunde
void Add_one_Second (void)
//################################################## ##########################
{
ss++;//Addiere +1 zu Sekunden
if (ss == 60)
{
ss = 0;
mm++;//Addiere +1 zu Minuten
if (mm == 60)
{
mm = 0;
hh++;//Addiere +1 zu Stunden
if (hh == 24)
{
hh = 0;
if (hh== 0)
{
day++;//Addiere +1 zu Tag

}
}
}
}

}

//################################################## ##########################
//Diese Routine startet und initialisiert den Timer
void Start_Clock (void)
//################################################## ##########################
{

//Timer 1 Overflow einschalten
TIMSK |= (1 << TOIE1);
//Prescaler auf 1024 setzen
TCCR1B |= (1<<CS10 | 0<<CS11 | 1<<CS12);
//Timer 1 auf 0 setzen
TCNT1 = 65535 - (SYSCLK / 1024);
}

Moritz f.
07.01.2008, 06:59
Hallo,
schau mal ob die Interruptroutine (nur) ein mal aufgerufen wird. Das war bei mir nämlich eben erst der Fall. Habs inzwischen behoben, aber warum das jetzt funktioniert weiß ich leider noch nicht.

Mit meiner Lösung würde das so aussehen:


ISR(TIMER1_OVF_vect)
{
cli(); //Global Interrupt Flag löschen
TCNT1 = 65535 - (SYSCLK / 1024); //Zurücksetzen des Timers
Add_one_Second (); //1 Sekunde addieren
sei(); //Global Interupt Flag wieder setzten
}


Vielleicht funktionierts ;)

lg MoFe

ps: Bitte [ code] Source Code [ /code] verwenden, mach das ganze übersichtlicher.

Hubert.G
07.01.2008, 09:42
Und auch den gesamten Code zeigen, denn warum bist du dir sicher das der Fehler gerade in dem Bereich liegt. Man sieht z.B. nicht ob du sei(); gesetzt hast.
Es wäre ausserdem Übersichtlicher und vom Code her kürzer, wenn du den OutputComparematch Interrupt benutzen würdest.

steffen21m
07.01.2008, 18:02
Hallo noch mal ...
Danke für die schnellen Antworten. Habe die Lösung von Moritz probiert. Funzt leider immer noch nicht.
Hier ist noch der restliche Quellcode (Danke Hubert)

//Hauptprogramm
int main (void)
//################################################## ##########################
{
//Globale Interrupts einschalten
sei();


//Starten der DCF77 Uhr
Start_Clock();

usart_write ("\nDCF 77 Ho Ho Ho Jo\n\n");
//Ausgabe der Zeit auf der Seriellen Schnittstelle in einer Endlosschleife
while (1)
{

if (TCNT1==65535)
{
TCNT1 = 65535 - (SYSCLK / 1024);
Add_one_Second();

}

}

return (1);
}


Wenn ich die roten Zeilen statt der ISR einbaue funktioniert alles (sind die gleichen Zeilen wie in der ISR). Warum funzt dann die ISR nicht ?

Gruß Steffen

McJenso
07.01.2008, 19:17
Hallo,


ps: Bitte [ code] Source Code [ /code] verwenden, mach das ganze übersichtlicher.
Ist das so schwer? ](*,)

Wird die ISR wirklich nicht aufgerufen oder nur der Code nicht so ausgeführt wie du möchtest?
Deklariere mal alle Variablen ,die innerhalb der ISR also auch innerhalb von 'Add_one_Second' genutzt werden, als volatile.

BTW. SYSCLK wird ja sicher im Header definiert sein. 65535-(SYSCLK/1024) ist damit auch konstant. Würde ich auch im Header definieren.

Gruß

Jens