Forum: Mikrocontroller und Digitale Elektronik erste Schritte mit Atmega8 und LED


von Boris (Gast)


Lesenswert?

Hallo,
ich habe folgendes Programm zum schalten von 2 Ausgängen mit 2 Tastern, 
zur Simulation benutze ich z.Zt. die LED´s auf dem STK500. Da ich gerade 
erst mit der Progammierung des Atmega8 anfange habe ich folgende Frage 
dazu. Bitte wie oder was kann ich einbauen, um die Ausgänge zeitlich zu 
halten ? Z.B. drücken des Tasters - LED ist 5 Sekunden an und geht dann 
aus.
Also wie geht das ???

Gruss
Boris

______________________________________________________________________ 
_
#include <avr/io.h>

int main (void)
{

DDRB &= ~( 1 << PB0 ); //PB0 Eingang
DDRB &= ~( 1 << PB1 ); //PB1 Eingang
PORTB |= ( 1 << PB0 ); //Pull up an
PORTB |= ( 1 << PB1 ); //Pull up an
DDRC |= ( 1 << PC0 ); //PC0 Ausgang
DDRC |= ( 1 << PC1 ); //PC1 Ausgang

while(1)
{
if (PINB & (1 << PB0))//wenn PB0 High ist...
{
PORTC |= (1 << PC0); //PC0 High
}
if (PINB & (1 << PB1))//wenn PB1 High ist...
{
PORTC |= (1 << PC1); //PC1 High
}
// Eine Schleife
if (!(PINB & (1 << PB0))) //wenn PB0 Low ist...
{
PORTC &= ~(1 << PC0); //PC0 Low
}
if (!(PINB & (1 << PB1))) //wenn PB1 Low ist...
{
PORTC &= ~(1 << PC1); //PC1 Low
}

}

return 0;
}
______________________________________________________________________ 
__

von Niels H. (monarch35)


Lesenswert?

Zeitsteuerungen macht man in der Regel mit Timern. Zu einem bestimmten 
Ereignis (z.B. Tastendruck) startet man den Timer, der daraufhin 
zeitversetzt wieder ein Ereignis auslöst (Overflow_Interrupt oder 
CompareMatch, je nach modus).

siehe dazu:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Die_Timer.2FCounter_des_AVR

Du kannst es auch mit einfachen Pausenschleifen realisieren, ist aber 
weniger elegant.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Letztens war im GCC Forum ein guter Artikel zu sog. state machines 
(endliche Automaten)

Auf dein Beispiel übertragen, sieht das so aus:

Deine Maschine kennt genau zwei Zustände - LED ist aus (Zustand LED_AUS) 
und LED ist an (Zustand LED_AN). Die Anfangsbedingung sei mal, dass die 
LED aus ist.

Vom Zustand LED_AUS kommt man in den Zustand LED_AN, indem man einen 
Taster drückt.

Vom Zustand LED_AN kommt man in den Zustand LED_AUS, indem man 5 
Sekunden wartet. Ein Drücken des Tasters im Zustand LED_AN ist 
wirkungslos.

Also sieht die Grundroutine so aus
1
#include <avr/io.h>
2
#ifndef F_CPU
3
/* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert 
4
   (z.B. durch Übergabe als Parameter zum Compiler innerhalb 
5
   des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die
6
   "nachträgliche" Definition hinweist */
7
#warning "F_CPU war noch nicht definiert, wird nun mit 1000000 definiert"
8
#define F_CPU 1000000UL
9
#endif
10
#include <util/delay.h>
11
12
// Symbolische Namen für die Zustände
13
// Beliebig wählbar, müssen aber unterscheidbar sein
14
#define LED_AN  23
15
#define LED_AUS 42
16
17
// Hardwarefummeleien an einer Stelle im Quellcode gibt 
18
// bessere Lesbarkeit im Programm unten und eine Stelle 
19
// zentral fürs Entwanzen oder Hardwareanpassen...
20
#define LED_PC0_ANSCHALTEN()     do { PORTC &= ~(1 << PC0); } while(0)
21
#define LED_PC0_AUSSCHALTEN()    do { PORTC |=  (1 << PC0); } while(0)
22
#define TASTER_PB0_GEOEFFNET()   (PINB & (1 << PB0))
23
#define TASTER_PB0_GESCHLOSSEN() !(TASTER_PB0_GEOEFFNET())
24
25
// http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Warteschleifen_.28delay.h.29
26
void warte_5s(void)
27
{
28
  unsigned char i, j;
29
30
  for (i=0; i<5 ; i++)      // 5 * 100 * 10 ms = 5000 ms = 5 s
31
    for (j=0; j<100; j++)
32
      _delay_ms(10);        // funktioniert bis F_CPU 20 MHz
33
}
34
35
int main(void)
36
{
37
  unsigned char zustand;
38
39
  // Hardware vorbereiten
40
  DDRB  &= ~( 1 << PB0 ); //PB0 Eingang
41
  PORTB |=  ( 1 << PB0 ); //Pull up an
42
  DDRC  |=  ( 1 << PC0 ); //PC0 Ausgang
43
44
  // Anfangsbedingung setzen
45
  zustand = LED_AUS;
46
  LED_PC0_AUSSCHALTEN();
47
48
  while(1)
49
  {
50
    if (zustand == LED_AUS)
51
    {
52
       // Taster abfragen, ob Zusand gewechselt werden soll            
53
       if (TASTER_PB0_GESCHLOSSEN())
54
       {
55
          // Zustand wechseln
56
          zustand = LED_AN;
57
58
          // Dafür sorgen, dass die Hardware in diesen Zustand kommt
59
          LED_PC0_ANSCHALTEN();
60
       }
61
    }
62
    else if (zustand == LED_AN)
63
    {
64
       warte_5s();
65
66
       // Zustand wechseln
67
       zustand = LED_AUS;
68
69
       // Dafür sorgen, dass die Hardware in diesen Zustand kommt
70
       LED_PC0_AUSSCHALTEN();
71
    }
72
  }
73
}

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

Boris... schonmal was von Code-Formatierung (Indention) gehoert?

Das Beispiel von Stefan verwendet aktives warten, das ist nicht sehr 
optimal, vor allem, wenn Dein Programm noch andere Dinge tun soll. Ein 
timer ist hier besser geeignet...

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.