Hallo Community, ich habe, aufbauend auf einem Beispielcode von Karl Heinz Buchegger, nur noch eine Funktion zu implementieren und es dann echt geschafft - aber die bereitet mir momentan probleme: Ich möchte über einen hardwareentprellten taster und dem INT0 Interrupt bestimmen, ob der µC die Funtion "signal_event" in der mainschleife ausführt oder nicht. Zum wechseln ob ja oder nein, dachte ich an die if-bedingungen im ISR und eine globale boolvariable. Bei meinem Code wird über den INT0 immer nur der zweite teil der ifbedingung ausgeführt, das heißt die bool ändert sich nicht. Könnt ihr mir sagen, was ich falsch mache? Sehr viel mehr code passt nicht rein, bin momentan bei ca 88%.
1 | #include <stdbool.h> |
2 | #include <stdlib.h> |
3 | #include <stdint.h> |
4 | |
5 | #include <avr/io.h> |
6 | #include <avr/interrupt.h> |
7 | #include <avr/power.h> |
8 | #include <avr/sleep.h> |
9 | |
10 | #define F_CPU 9.6E6
|
11 | #include <util/delay.h> |
12 | |
13 | #define CLOCK_PRESCALER 256
|
14 | #define TIMER_PRESCALER 1024
|
15 | |
16 | #define TIMER_PERIOD (256 / (F_CPU / CLOCK_PRESCALER / TIMER_PRESCALER))
|
17 | |
18 | #define MEDIAN ( 1 * 60) /* 10 minutes */ |
19 | |
20 | static uint16_t countdown; |
21 | static volatile bool timer_expired; |
22 | volatile bool on; |
23 | |
24 | |
25 | ISR(TIM0_OVF_vect) |
26 | {
|
27 | if (--countdown == 0) { |
28 | TCCR0B = 0; /* turn off timer */ |
29 | timer_expired = true; |
30 | clock_prescale_set(clock_div_1); |
31 | }
|
32 | }
|
33 | |
34 | ISR(INT0_vect) |
35 | {
|
36 | if (on) |
37 | {
|
38 | on = false; |
39 | |
40 | PORTB |= (1<<PB4); // LED 2*flashing: Off |
41 | _delay_ms(20); |
42 | PORTB &= ~(1<<PB4); |
43 | _delay_ms(20); |
44 | PORTB |= (1<<PB4); |
45 | _delay_ms(20); |
46 | PORTB &= ~(1<<PB4); |
47 | _delay_ms(20); |
48 | }
|
49 | else if (!on) |
50 | {
|
51 | on = true; |
52 | |
53 | PORTB |= (1<<PB4); // LED 1*flashing: On |
54 | _delay_ms(20); |
55 | PORTB &= ~(1<<PB4); |
56 | _delay_ms(20); |
57 | }
|
58 | }
|
59 | |
60 | static void starttimer(uint16_t timeout) |
61 | {
|
62 | countdown = timeout; |
63 | TCNT0 = 0; |
64 | timer_expired = false; |
65 | clock_prescale_set(clock_div_256); |
66 | TCCR0B = _BV(CS02) | _BV(CS00); /* start timer with prescaler 1024 */ |
67 | }
|
68 | |
69 | static void ioinit(void) |
70 | {
|
71 | TIMSK0 = _BV(TOIE0); |
72 | GIMSK |= (1<<INT0); |
73 | MCUCR |= (1<<ISC01); // Falling edge |
74 | MCUCR &= ~(1<<ISC00); // INT0 detection |
75 | |
76 | sei(); |
77 | DDRB = _BV(4); /* connection for LED or something else */ |
78 | }
|
79 | |
80 | static void signal_event(void) |
81 | {
|
82 | PORTB |= _BV(4); |
83 | _delay_ms(1000); |
84 | PORTB &= ~_BV(4); |
85 | }
|
86 | |
87 | int
|
88 | main(void) |
89 | {
|
90 | ioinit(); |
91 | |
92 | for (;;) { |
93 | int r = rand(); |
94 | uint16_t timeout = (unsigned)r % (unsigned)(2 * MEDIAN / TIMER_PERIOD) + 1; |
95 | |
96 | starttimer(timeout); |
97 | do
|
98 | {
|
99 | sleep_mode(); |
100 | }
|
101 | while (!timer_expired); |
102 | |
103 | if (on) |
104 | signal_event(); |
105 | }
|
106 | }
|
Beste Grüße