Forum: Compiler & IDEs LED x-mal blinken lassen mit Timer


von Paul (Gast)


Lesenswert?

Hallo,

ich mache gerade meine ersten Gehversuche mit dem AtMega8. Leider 
schaffe ich es (aus eigener Blödheit) nicht eine LED eine bestimmte 
Anzahl mal blinken zu lassen. Bisher sieht mein Code so aus:

#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/delay.h>


volatile uint8_t count=0;

ISR(TIMER0_OVF_vect)
{
    count++;
}
void schalte_led()
{
  if(count>=5)
    PORTB |= (1<<PB3);
  if(count>=10)
  {
    PORTB &= ~(1<<PB3);    // LED aus
    count=0;
  }
}
int main(void)
{
   TCCR0 = (1<<CS02);     // Overflow-Modus, prescaler /256
   DDRB |= 0xFF;           // LED an einem Ausgang
   PORTB = 0xFF;    // LED aus
   TIMSK |= (1<<TOIE0);
   sei();

  while(1)
  {
    schalte_led();
  }

}

Nun würde ich der Funktion schalte_led gerne noch einen Parameter 
mitgeben, der bestimmt, wie oft geblinkt werden soll. Kann mir jemand 
einen Tipp geben? Meine bisherigen Versuche sind leider fehlgeschlagen.
Lieber Gruß
Paul

von Paul (Gast)


Lesenswert?

P.S: Das "#include <util/delay.h>" ist ein Überbleibsel diverser Tests.

von Michael D. (Gast)


Lesenswert?

if count >= 10 wahr
dann
if count >= 5  auch wahr

von Paul (Gast)


Lesenswert?

if count >= 10 wahr
dann
if count >= 5  auch wahr

Ja, das ist natürlich Quatsch, Danke.

von Michael D. (etzen_michi)


Lesenswert?

Nun auch angemeldet

Ich würde das über einen SwitchCase machen, der bei 5 und 10 schaltet 
(Die kurze aktion kann man noch in der ISR machen würde ich sagen.

Bei jedem Ausschalten der LED eine volatile +1
und vor dem SwitchCase eine for


for(;i<wieoft;) {
    switch(++count) {

        case 5:
            PORTB |= (1<<PB3);
            break;

        case 10:
            PORTB &= ~(1<<PB3);
            count=0;
            wieoft++;
            break;

        default:
            break;
    }
}

von Krapao (Gast)


Lesenswert?

1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
volatile uint8_t count = 0;
5
6
ISR(TIMER0_OVF_vect)
7
{
8
  count++;
9
}
10
11
void schalte_led(int blink_zyklen)
12
{
13
  static int erledigte_blink_zyklen = 0;
14
15
  if ( blink_zyklen == -1 )
16
    erledigte_blink_zyklen = 0; // Möglichkeit zum Zurücksetzen
17
18
  if ( erledigte_blink_zyklen < blink_zyklen )
19
  {
20
    if( count >= 5 )
21
    {
22
      PORTB |= (1<<PB3); // LED an
23
    }
24
25
    if( count >= 10 )
26
    {
27
      PORTB &= ~(1<<PB3); // LED aus
28
      count = 0;
29
      erledigte_blink_zyklen++;
30
    }
31
  }
32
}
33
34
int main(void)
35
{
36
  DDRB |= (1<<PB3);    // PORTB.3 Ausgang
37
  PORTB &= ~(1<<PB3);  // LED aus
38
39
  /*
40
   8-Bit Timer0 Overflow-Modus, Prescaler /256
41
   Aufruf der ISR alle 1 / F_CPU / Prescaler / 2^8 s
42
   Z.B. 65,536 ms bei 1 MHz
43
   Softwarezähler 5 => ~300ms AN/AUS Phasen
44
   */
45
  TCCR0 = (1<<CS02);
46
  TIMSK |= (1<<TOIE0);
47
  sei();
48
49
  while(1)
50
  {
51
    schalte_led(3);
52
  }
53
}

von Paul (Gast)


Lesenswert?

Ihr seid ganz, ganz Toll! Vielen Dank!
Hab vorher nie mit Interrupts programmiert, da fällt mir das ein wenig 
schwer.
Schönes WE
Paul

von Michael D. (etzen_michi)


Lesenswert?

static int erledigte_blink_zyklen = 0;


Verstehe ich nicht ganz ... die willst du doch hochzählen wenn ichd as 
richtig verstehe. Ich dachte das geht bei static nicht.

Bitte info wenn ich mich irre.

von Krapao (Gast)


Lesenswert?

Das Schlüsselwort static bedeutet, dass der Wert von 
erledigte_blink_zyklen zwischen den Aufrufen von schalte_led 
erhalten bleibt. Nicht Verwechseln mit dem Schlüsselwort const!

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.