www.mikrocontroller.net

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


Autor: Boris (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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;
}
______________________________________________________________________ 
__

Autor: Niels Hüsken (monarch35)
Datum:

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

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

Autor: Stefan B. (stefan) Benutzerseite
Datum:

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

#include <avr/io.h>
#ifndef F_CPU
/* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert 
   (z.B. durch Übergabe als Parameter zum Compiler innerhalb 
   des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die
   "nachträgliche" Definition hinweist */
#warning "F_CPU war noch nicht definiert, wird nun mit 1000000 definiert"
#define F_CPU 1000000UL
#endif
#include <util/delay.h>

// Symbolische Namen für die Zustände
// Beliebig wählbar, müssen aber unterscheidbar sein
#define LED_AN  23
#define LED_AUS 42

// Hardwarefummeleien an einer Stelle im Quellcode gibt 
// bessere Lesbarkeit im Programm unten und eine Stelle 
// zentral fürs Entwanzen oder Hardwareanpassen...
#define LED_PC0_ANSCHALTEN()     do { PORTC &= ~(1 << PC0); } while(0)
#define LED_PC0_AUSSCHALTEN()    do { PORTC |=  (1 << PC0); } while(0)
#define TASTER_PB0_GEOEFFNET()   (PINB & (1 << PB0))
#define TASTER_PB0_GESCHLOSSEN() !(TASTER_PB0_GEOEFFNET())

// http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Warteschleifen_.28delay.h.29
void warte_5s(void)
{
  unsigned char i, j;

  for (i=0; i<5 ; i++)      // 5 * 100 * 10 ms = 5000 ms = 5 s
    for (j=0; j<100; j++)
      _delay_ms(10);        // funktioniert bis F_CPU 20 MHz
}

int main(void)
{
  unsigned char zustand;

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

  // Anfangsbedingung setzen
  zustand = LED_AUS;
  LED_PC0_AUSSCHALTEN();

  while(1)
  {
    if (zustand == LED_AUS)
    {
       // Taster abfragen, ob Zusand gewechselt werden soll            
       if (TASTER_PB0_GESCHLOSSEN())
       {
          // Zustand wechseln
          zustand = LED_AN;

          // Dafür sorgen, dass die Hardware in diesen Zustand kommt
          LED_PC0_ANSCHALTEN();
       }
    }
    else if (zustand == LED_AN)
    {
       warte_5s();

       // Zustand wechseln
       zustand = LED_AUS;

       // Dafür sorgen, dass die Hardware in diesen Zustand kommt
       LED_PC0_AUSSCHALTEN();
    }
  }
}


Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

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

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.