Timer 1 lässt LED nicht blinken

Gast #1865644
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
#1865656
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.
Gast #1865663
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.
:-)
#1865680
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.
#1865821
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

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