PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] ATMEGA16 - Timer zerschossen?



Kesandal
19.06.2011, 16:59
Hallo,

ich verzweifle langsam.

Nach 2 Stunden rumprobierere möchte ich mich hier an Euch wenden.
Testen wollte ich ein älteres Programm von mir.
Damals funktionierte es - jede Sekunde die LEDs am STK500 kurz aufblitzen.

Jetzt kriege ich es zum verrecken nicht ans laufen.
Egal welches Programm wo ich mit ISR arbeite.


Code:


#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/delay.h>;

#define SYSTEMCLOCK 3686400;


unsigned char counter;

unsigned char helper;

int main(){
counter = 0;

DDRD=0xff;

TCCR0 = (1<<CS02)|(1<<CS00); // 1024

TCNT0=0;

TIMSK = (1<<TOIE0);
// 14hz, d.h. 14x in der Sekunde ein overflow



sei();

while(1){

}

return 0;
}

ISR(TIMER0_OVF_vect){
counter++;
if(counter==14){
PORTD=0x00;
_delay_ms(50);
PORTD=0xff;
counter=0;
}
}
Beispiel 2 (von einer Webseite) das nicht funktioniert:



#include <avr/io.h>
#include <avr/interrupt.h>

volatile uint8_t count;

void main()
{
// Prescaler = FCPU/1024
TCCR0|=(1<<CS02)|(1<<CS00);

//Enable Overflow Interrupt Enable
TIMSK|=(1<<TOIE0);

//Initialize Counter
TCNT0=0;

//Initialize our varriable
count=0;

//Port D[3,2,1,0] as out put
PORTD|=0x0F;

//Enable Global Interrupts
sei();

//Infinite loop
while(1);
}

ISR(TIMER0_OVF_vect)
{
//This is the interrupt service routine for TIMER0 OVERFLOW Interrupt.
//CPU automatically call this when TIMER0 overflows.

//Increment our variable
count++;
if(count==61)
{
PORTD=~PORTD; //Invert the Value of PORTD
count=0;
}
}



Beispiel 3 (von unserem Professor) - das auch nicht mehr funktioniert..
Alle LEDs bleiben einfach an:



/* Aufblitzen der LEDs im Sekundentakt
mit Timer 0

Systemclock 3686400 Hz
Prescaler = 1024, ergibt Timer0-Takt von 3600 Hz
Timer0 zaehlt nur bis 36,
ergibt also alle 10 ms einen Ueberlauf.
Waehrend 50 ms werden die LEDs eingeschaltet.
*/

#include <avr/io.h>

#define SYSTEMCLOCK 3686400

int main(void) {
unsigned int t=0;

/* set up compare register */

OCR0=36;

/* Set up ports for the right direction of data flow */

DDRD=0xff; /* PD is output, should be connected to LEDs */

/* Set up timer mode */

TCCR0=(1<<WGM01)|(1<<CS02)|(1<<CS00); /* choose CK/1024, clear on compare match */

while(1) {
while(!(TIFR&_BV(OCF0))) {}; /* wait for compare match */
TIFR=_BV(OCF0); /* clear flag */
t+=1;
if(t==95) PORTD=0;
if(t==100) {
PORTD=0xff;
t=0;
}
}

return 0;
}



Hat jemand eine Idee warum es nicht funktioniert?

Danke
Kesandal


Edit: Ich habe zum Test noch einen ATMEGA32 genommen.
Auch hier funktioniert es nicht...

Ich stehe grad auf'm Schlauch.. :(

Besserwessi
19.06.2011, 17:17
Das beim µC nur der Timer nicht mehr geht ist recht unwahrscheinlich.

Kann es sein, das der Compiler aktualisiert wurde ? Gerade bei Interrupts hat sich bei GCC was verändert von Version 3.xx nach 4.xx.

Die Zuweisung SYSTEMCLOCK 3686400 kommt mir so auch nicht bekannt vor. Der Systemtakt wird aber auch noch einmal in der Optionen (bei WinaAVR) eingestellt. Wenn man delay_ms verwendet, muss mit Optimierung gearbeitet werden. Sonst werden die Zeiten viel zu lang.

Die variable counter sollte man der Sicherheit halber noch als volatile markieren, auch wenn ich nicht glaube das es hier die Ursache für das Problem ist.

Bleibt noch die Frage, was denn nicht funktioniert ?

Kesandal
19.06.2011, 17:25
Hallo und danke für Deine Antwort.

Ich habe mein Windows neu aufgesetzt.
Installiert habe ich AVR Studio 5 sowie Studio 4.
Verwenden tue ich Version 4.

GCC (WinAVR) habe ich die vor 3 oder 4 Tagen heruntergeladen.
Die neuste Version ist von 2010. Müsste also schon vor meiner Neuinstallation diese Version verwendet haben.



SYSTEMCLOCK :
Das haben wir bei uns im Kurs immer verwendet.
Ja, dass Menü im AVRStudio kenne ich. Dort ist die Freq. auf ~ 3.6 Mhz eingestellt.



Die variable counter sollte man der Sicherheit halber noch als volatile markieren, auch wenn ich nicht glaube das es hier die Ursache für das Problem ist.Erledigt. Brachte aber keine Besserung.



Bleibt noch die Frage, was denn nicht funktioniert ? Beim Programm 1: Alle LEDs brennen einfach.

Edit: Noch eine Erkentniss: Ich behaupte die ISR wird garnicht aufgerufen.
Denn wenn ich kurz vor sei() alle LEDs ausschalte und in die ISR lediglich die LEDs einschalte
bleiben die LEDs ebenfalls aus.

radbruch
19.06.2011, 17:32
Sollte es nicht

#define F_CPU 3686400

lauten? Und counter sollte vielleicht so definiert sein:

volatile unsigned char counter;

Oder alternativ lokal und statisch in der ISR:

ISR(TIMER0_OVF_vect){

static unsigned char counter=0;

counter++;
...

Edit: Ich bin zu langsam...

TobiKa
19.06.2011, 17:33
//Port C[3,2,1,0] as out put
PORTD|=0x0F;

Was denn nun, C oder D?!

Kesandal
19.06.2011, 17:39
//Port C[3,2,1,0] as out put
PORTD|=0x0F;
Was denn nun, C oder D?!

Der Kommentar war falsch. PORTD|=0x0F; ist korrekt.




Und counter sollte vielleicht so definiert sein:

volatile unsigned char counter;
Auch probiert. :(


Nochmal ein Zitat von mir selbst:


Beim Programm 1: Alle LEDs brennen einfach.

Edit: Noch eine Erkentniss: Ich behaupte die ISR wird garnicht aufgerufen.
Denn wenn ich kurz vor sei() alle LEDs ausschalte und in die ISR lediglich die LEDs einschalte
bleiben die LEDs ebenfalls aus.


Vielleicht hilft diese Information weiter?

Kesandal
19.06.2011, 18:50
Update:

Ich habe es zum laufen bekommen.

Woran es gelegen hat weiß ich nicht.
Ich habe ein neues Projekt in AVR Studio erstellt.

Nun funktioniert alles.

Danke für Eure Vorschläge und Hilfen ! :)