Atmega32 und Timer0 funktioniert nicht

Gast #1688646
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
Gast #1688655
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
Gast #1688666
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
}
Gast #1688711
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
Gast #1688738
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.
Gast #1688775
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
#1688894
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
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren