Forum: Compiler & IDEs Atmega32 und Timer0 funktioniert nicht


von NoName (Gast)


Lesenswert?

Hallo,
will gerade den Timer0 beim Atmega32 programmieren.
Es klappt jedoch nicht so wie ich will.
Mein Atmega taktet mit 16.000 Mhz

Hier mal mein Quellcode:
1
#include <avr/io.h>
2
#include <stdint.h>
3
#include <avr/interrupt.h>
4
//--------------------------
5
6
volatile unsigned int timer = 0;
7
8
ISR(TIMER0_OVF_vect)
9
{
10
   timer++;
11
   if(timer>= 20)
12
   {
13
      PORTA = ~PORTA; //Leds invertieren
14
   }
15
   TCNT2 = 0;
16
}
17
18
int main (void)
19
{
20
  DDRA = 0xff;
21
  PORTA = 0xff;
22
23
  TCCR2 = (1<<CS02) | (1<<CS00);
24
  TCNT2  = 0;
25
  TIMSK = (1<<TOIE0);
26
27
  sei();
28
29
  while(1)
30
  {  
31
    
32
  }
33
  return(0);    
34
}

Ich weis nicht wo der Fehler ist. Aber irgendwie wollen die Leds nicht 
blinken. Sie gehn einfach nur an.

Danke für eure Hilfe

von Lord Z. (lordziu)


Lesenswert?

NoName schrieb:
> PORTA = ~PORTA; //Leds invertieren

PORTA = PINA;

von Stefan E. (sternst)


Lesenswert?

NoName schrieb:
> Ich weis nicht wo der Fehler ist.

Du startest Timer 2, nicht 0.

von Oliver (Gast)


Lesenswert?

Du solltes dich mal entscheiden, ob du nun mit Timer0 oder mit Timer2 
arbeiten willst.

Und wenn dann deine ISR mal öfter aufgerufen wird, musst du schon 
abwarten, bis die Variable timer überläuft. Erst dann wird die wieder 
kleiner als 20.

Oliver

von NoName (Gast)


Lesenswert?

Hallo
ich weis nicht wieso ich da immer den Timer2 genommen habe.
Danke aufjedenfall.

Hier nochmal der funktionierende Quelltext:
1
#include <avr/io.h>
2
#include <stdint.h>
3
#include <avr/interrupt.h>
4
//--------------------------
5
6
volatile unsigned int timer = 0;
7
8
9
ISR(TIMER0_OVF_vect)
10
{
11
   timer++;
12
   if(timer>= 100)
13
   {
14
     PORTA = ~PORTA;
15
     timer=0;
16
   }
17
   TCNT0 = 0;
18
}
19
20
int main (void)
21
{
22
  DDRA = 0xff;
23
  PORTA = 0xff;
24
25
  TCCR0 = (1<<CS02) | (1<<CS00);
26
  TCNT0  = 0;
27
  TIMSK = (1<<TOIE0);
28
29
  sei();
30
31
  while(1)
32
  {  
33
    
34
  }
35
  return(0);    
36
}

von Oliver (Gast)


Lesenswert?

Wenn du dir jetzt noch mal Gedanken über das
1
 TCNT0 = 0;
 in der ISR machst, und dabei rekapitulierst, wann ein "Timer Overflow 
Interrupt" ausgelöst wird, wird es noch besser.

Oliver

von NoName (Gast)


Lesenswert?

das brauch ich dann nicht weil es dann so oder so wieder auf null geht?

von Oliver (Gast)


Lesenswert?

NoName schrieb:
> das brauch ich dann nicht weil es dann so oder so wieder auf null geht?

So oder so ähnlich...

Oliver

von NoName (Gast)


Lesenswert?

ja ist doch so:

 11111111 <- 255
100000000 <- Overflow und das 8te Bit fällt weg
 00000000 -> entspricht 0

oder irre ich mich da?

von Karl H. (kbuchegg)


Lesenswert?

NoName schrieb:
> ja ist doch so:
>
>  11111111 <- 255
> 100000000 <- Overflow und das 8te Bit fällt weg
>  00000000 -> entspricht 0
>
> oder irre ich mich da?

Nein, du irrst dich nicht.

Generell: Lass den Timer in Ruhe arbeiten. Pfusche ihm nicht am 
Zählerstand rum.

von Oliver (Gast)


Lesenswert?

NoName schrieb:
> oder irre ich mich da?

Nein. In deinem Programm ist das so, daß de Timer an der Stelle, wo du 
ihn manuell auf 0 setzt, schon von selber 0 ist. Da schadet dein 
Nullsetzen nicht, es nutzt aber auch nichts.

Wenn du aber irgendwann mal ein ähnliches Programm schreibst, in dem der 
Timer mit einer schnelleren Taktrate arbeitet, könnte der bis zu dem 
manuellen Nullungsbefehl schon wieder bis 1, 2, oder noch weiter gezählt 
haben. Wenn du den dann manuell auf Null setzt, stimmt das Timing nicht 
mehr. Daher, wie Karl Heinz schon schrieb, lass den Timer Timer sein. 
Der macht das schon.

Oliver

von NoName (Gast)


Lesenswert?

ok, danke für den tip.

ich habe mal mein programm erweitert.
1
#include <avr/io.h>
2
#include <stdint.h>
3
#include <avr/interrupt.h>
4
//--------------------------
5
6
volatile unsigned int timer = 0;
7
volatile unsigned int adwert = 0;
8
9
void wait(unsigned int time)
10
{
11
   timer = 0;
12
   while(timer<time)
13
   {
14
   }
15
}
16
17
ISR(ADC_vect)
18
{
19
  adwert = ADCH;
20
  ADCSRA = 0xC8;
21
}
22
23
ISR(TIMER0_OVF_vect)
24
{
25
   timer++;
26
}
27
28
int main (void)
29
{
30
  DDRA = 0xff;
31
  PORTA = 0xff;
32
33
  TCCR0 = (1<<CS02) | (1<<CS00);
34
  TCNT0 = 10;
35
  TIMSK = (1<<TOIE0);
36
37
  ADMUX = 0x24;
38
  SFIOR = 0x00;
39
  ADCSRA = 0xC8;
40
41
  sei();
42
43
  while(1)
44
  {  
45
  wait(adwert);
46
  PORTA = ~PORTA;
47
  }
48
  return(0);    
49
}

Jedoch verhält sich das Programm komisch.
Die wait Funktion klappt mit festen werten und auch der AD-Wandler 
klappt alleine.

von NoName (Gast)


Lesenswert?

hallo,
ich glaub heute ist nicht mein tag.
wenn man zwei quelltexte kopier ist nicht so gut habe ich gerade 
festgestellt....

ich habe vergessen den AD Port als eingan zu definieren, jetzt tuts...

Danke jetzt klappt alles was ich wollte

von Karl H. (kbuchegg)


Lesenswert?

1
void wait(unsigned int time)
2
{
3
   timer = 0;
4
   while(timer<time)
5
   {
6
   }
7
}

so einfach ist die Sache nicht.
Da timer eine 16 Bit Variable ist, muss der µC alle Zugriffe auf diese 
Variable in 2 Häppchen erledigen. Und zwischen diesen beiden Häppchen 
sollte dir tunlichst kein Interrupt dazwischenfunken, sonst gibts 
Datensalat.
1
void wait(unsigned int time)
2
{
3
   unsigned int now;
4
5
   cli();
6
   timer = 0;
7
   sei();
8
9
   do {
10
     cli();
11
     now = timer;
12
     sei();
13
   } while( now < time );
14
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.