Forum: Compiler & IDEs Timer 1 lässt LED nicht blinken


von Lars (Gast)


Lesenswert?

1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <stdint.h>
4
#define F_CPU 4000000UL
5
6
volatile unsigned int Counter=0; //Counter für Timer
7
uint16_t i=0; //Zählervariable i
8
9
10
ISR(TIMER1_COMPA_vect)
11
{
12
//PORTD ^= (1<<PD2);
13
Counter++;
14
}
15
16
int main(void)
17
{
18
19
DDRD=0xff;  //Portd als Ausgang
20
21
TCCR1B=(1<<WGM12)|(1<<CS12)|(1<<CS10);   //CTC und Teiler:1024
22
OCR1A =(uint16_t)(F_CPU/1024);       //Overflow-Wert aber gerundet
23
TIMSK =(1<<OCIE1A);             //Overflow Interrupt einschaten
24
25
sei();                     //Interrupt aktivieren
26
27
while(1)
28
{
29
30
if (Counter >=1)
31
{
32
Counter =0;
33
if(i==0){
34
PORTD |=(1<<PD2); //PortD Pin1 auf high
35
i=1;
36
}
37
else
38
{
39
i=0;
40
PORTD &= ~(1<<PD2); // PortD Pin1 auf low
41
}
42
}
43
}//while
44
45
}//main

Kann mir jemand sagen, warum die LED an PORTD mit dem Timer0 blink und 
wenn ich den Code auf Timer1 anpasse passiert nichts?
Vielen Dank
Grüße Lars

von Hc Z. (mizch)


Lesenswert?

Schau Dir mal die Logik nach „if (Counter >=1)“ an:  Die LED ist maximal 
für ein paar wenige µs an und wird dann sofort wieder im nächsten 
Schleifendurchlauf wieder ausgemacht.

Die Kommentierung ist etwas irreführend:  Es handelt sich nicht wie 
geschrieben um einen Overflow-Interrupt, sondern um den 
Compare-Interrupt.

von Floh (Gast)


Lesenswert?

Lars schrieb:
> Kann mir jemand sagen, warum die LED an PORTD mit dem Timer0 blink und
> wenn ich den Code auf Timer1 anpasse passiert nichts?

Du musst dich entscheiden, wann du die LED ansteuerst. Entweder im 
Interrupt, oder in der main. Beides in einem Programm ist Pfusch.

So als Arbeithinweis: Ich würd die while(true) in der main leermachen.
Dann dürfte es eigentlich schon funktionieren.
:-)

von Hc Z. (mizch)


Lesenswert?

Floh schrieb:
> Du musst dich entscheiden, wann du die LED ansteuerst. Entweder im
> Interrupt, oder in der main. Beides in einem Programm ist Pfusch.

Es ist sehr üblich, den Interrupt so kurz wie irgend möglich zu machen 
und nur eine Übergabe zu setzen.  Die Hauptarbeit wird dann später im 
Programm gemacht.

Bei einer LED mag das oversized sein, als Idee ist es durchaus üblich 
und in sehr vielen Situationen empfehlenswert und guter Stil.  Als Übung 
also gut geeignet.

von Karl H. (kbuchegg)


Lesenswert?

Ebenfalls guter Stil ist es, in seinem Programm die {-} blockmässige 
Hierarchiestruktur durch Einrückungen kenntlich zu machen. Und zwar 
nicht nur in einer Übung, sondern generell. Das bedeutet: Immer!
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <stdint.h>
4
#define F_CPU 4000000UL
5
6
volatile unsigned int Counter=0; //Counter für Timer
7
uint16_t i=0; //Zählervariable i
8
9
10
ISR(TIMER1_COMPA_vect)
11
{
12
  //PORTD ^= (1<<PD2);
13
  Counter++;
14
}
15
16
int main(void)
17
{
18
19
  DDRD = 0xff;  //Portd als Ausgang
20
21
  TCCR1B = (1<<WGM12)|(1<<CS12)|(1<<CS10);   //CTC und Teiler:1024
22
  OCR1A  = (uint16_t)(F_CPU/1024);       //Overflow-Wert aber gerundet
23
  TIMSK  = (1<<OCIE1A);             //Overflow Interrupt einschaten
24
25
  sei();                     //Interrupt aktivieren
26
27
  while(1)
28
  {
29
30
    if (Counter >= 1)
31
    {
32
      Counter = 0;
33
      if (i == 0)
34
      {
35
        PORTD |= (1<<PD2); //PortD Pin1 auf high
36
        i=1;
37
      }
38
      else
39
      {
40
        i=0;
41
        PORTD &= ~(1<<PD2); // PortD Pin1 auf low
42
      }
43
    }
44
  }//while
45
}//main

von Hc Z. (mizch)


Lesenswert?

Und wenn das denn richtig eingerückt gewesen wäre, hätte ich gesehen, 
dass

Hc Zimmerer schrieb:
> Die LED ist maximal
> für ein paar wenige µs an und wird dann sofort wieder im nächsten
> Schleifendurchlauf wieder ausgemacht.

nicht zutrifft.  Ich hatte das „else“ mangels Einrückung dem falschen 
„if“ zugeordnet.

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.