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; } ______________________________________________________________________ __
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.
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 | }
|
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.