Hallo zusammen,
ich habe ein kleines Projekt gestartet, damit ich meine
Eisenbahnbeleuchtung steuern kann.
Dazu habe ich insgesamt drei Taster (Schließer) vorgesehen, die
folgendes machen sollen:
- Wird Taster-1 gedrückt, soll immer wiederkehrend ein Blinkmuster
erfolgen (z.B. 3 sec. AN, 1 sec. AUS).
- Wird Taster-2 gedrückt, soll nur einmalig ein Muster ausgegeben werden
(z.B. 1 sec. AN, 3 sec. AUS, 2 sec. AN).
- Wird Taster-3 gedrückt, soll das wiederkehrende Blinkmuster (von
Taster-1) gelöscht werden und die LED ausgehen.
Hier der Code:
1 | #define F_CPU 8000000
|
2 |
|
3 | #include <avr/io.h>
|
4 | #include <avr/interrupt.h>
|
5 | #include <util/delay.h>
|
6 |
|
7 |
|
8 |
|
9 | #define TASTER_1 PINC4
|
10 | #define TASTER_2 PINC3
|
11 | #define TASTER_RESET PINC5
|
12 |
|
13 | #define OUTPUT_PORT PORTD
|
14 | #define OUTPUT_PIN PD0 // hier hängt die LED dran
|
15 |
|
16 | volatile unsigned char Taster;
|
17 |
|
18 |
|
19 | void init_timer_0(void)
|
20 | {
|
21 | TCCR0 |= (1 << CS02) | (1 << CS00); // Prescaler auf F_CPU / 1024
|
22 | TIMSK |= (1 << TOIE0); // overflow interrupt erlauben
|
23 | }
|
24 |
|
25 |
|
26 |
|
27 | ISR (TIMER0_OVF_vect) // Interrupt Service Routine (bei Timer-Overflow von Timer0)
|
28 | {
|
29 | if (!(PINC & (1 << TASTER_1))) { Taster = 1; }
|
30 | if (!(PINC & (1 << TASTER_2))) { Taster = 2; }
|
31 | if (!(PINC & (1 << TASTER_RESET))) { Taster = 0; }
|
32 |
|
33 | }
|
34 |
|
35 | void main (void)
|
36 | {
|
37 | Taster = 0;
|
38 |
|
39 | DDRC = 0; // Port C als Eingang
|
40 | PORTC = 0xFF; // interne Pullups aktivieren
|
41 |
|
42 | DDRD |= (1 << DDD0); // Port D als Ausgang
|
43 | OUTPUT_PORT = 0;
|
44 |
|
45 | init_timer_0();
|
46 | sei();
|
47 |
|
48 | while(1)
|
49 | {
|
50 | switch(Taster)
|
51 | {
|
52 | case 1:
|
53 | while(1)
|
54 | {
|
55 | OUTPUT_PORT |= (1 << OUTPUT_PIN); //wiederkehrendes Blinken
|
56 | _delay_ms(3000);
|
57 | OUTPUT_PORT &= ~(1 << OUTPUT_PIN);
|
58 | Taster=0;
|
59 | }
|
60 | break;
|
61 |
|
62 |
|
63 | case 2: // 1 sec. AN, 3 sec. AUS, 2 sec. AN
|
64 | OUTPUT_PORT |= (1 << OUTPUT_PIN);
|
65 | _delay_ms(1000);
|
66 | OUTPUT_PORT &= ~(1 << OUTPUT_PIN);
|
67 | _delay_ms(3000);
|
68 | OUTPUT_PORT |= (1 << OUTPUT_PIN);
|
69 | _delay_ms(2000);
|
70 | OUTPUT_PORT &= ~(1 << OUTPUT_PIN);
|
71 | Taster=0;
|
72 | break;
|
73 |
|
74 |
|
75 |
|
76 | case 0:
|
77 | OUTPUT_PORT &= ~(1 << OUTPUT_PIN); //...ausschalten
|
78 | break;
|
79 | }
|
80 | }
|
81 | }
|
Nun das Problem:
1.) Warum wird nach Tastendruck auf Taster-1 kein weiterer Tastendruck
mehr erkannt? Wie kann ich das machen, dass der Timer-Interrupt
registriert, dass während case 1 abgearbeitet wird, was gedrückt wurde?
2.) Ähnliches Problem: Warum löscht er mir das Blinken nicht, wenn ich
auf Taster-3 drücke?
Ich bin mir bewusst, dass die _delay_ms()-Routine ein rotes Tuch für
manche hier ist. Aber für den Zweck sollte das reichen! :-)
Vielen Dank euch!
Grüße