www.mikrocontroller.net

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


Autor: Lars (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>
#define F_CPU 4000000UL

volatile unsigned int Counter=0; //Counter für Timer
uint16_t i=0; //Zählervariable i


ISR(TIMER1_COMPA_vect)
{
//PORTD ^= (1<<PD2);
Counter++;
}

int main(void)
{

DDRD=0xff;  //Portd als Ausgang

TCCR1B=(1<<WGM12)|(1<<CS12)|(1<<CS10);   //CTC und Teiler:1024
OCR1A =(uint16_t)(F_CPU/1024);       //Overflow-Wert aber gerundet
TIMSK =(1<<OCIE1A);             //Overflow Interrupt einschaten

sei();                     //Interrupt aktivieren

while(1)
{

if (Counter >=1)
{
Counter =0;
if(i==0){
PORTD |=(1<<PD2); //PortD Pin1 auf high
i=1;
}
else
{
i=0;
PORTD &= ~(1<<PD2); // PortD Pin1 auf low
}
}
}//while

}//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

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
:-)

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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!
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>
#define F_CPU 4000000UL

volatile unsigned int Counter=0; //Counter für Timer
uint16_t i=0; //Zählervariable i


ISR(TIMER1_COMPA_vect)
{
  //PORTD ^= (1<<PD2);
  Counter++;
}

int main(void)
{

  DDRD = 0xff;  //Portd als Ausgang

  TCCR1B = (1<<WGM12)|(1<<CS12)|(1<<CS10);   //CTC und Teiler:1024
  OCR1A  = (uint16_t)(F_CPU/1024);       //Overflow-Wert aber gerundet
  TIMSK  = (1<<OCIE1A);             //Overflow Interrupt einschaten

  sei();                     //Interrupt aktivieren

  while(1)
  {

    if (Counter >= 1)
    {
      Counter = 0;
      if (i == 0)
      {
        PORTD |= (1<<PD2); //PortD Pin1 auf high
        i=1;
      }
      else
      {
        i=0;
        PORTD &= ~(1<<PD2); // PortD Pin1 auf low
      }
    }
  }//while
}//main

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.