Wie implementiert man eine retriggerbare monostabile Kippstufe? Ich habe etwas gefunden, zusammengesetzt und frisiert, aber gibt es vielleicht bessere, schönere Varianten? Vielen Dank im Voraus.
1 | /* -----------------------------------------------
|
2 | Retriggerable Monostable
|
3 | |
4 | ATtiny13A, 9.6MHz, CKDIV8
|
5 | |
6 | PB0 -- Pin 5 ---- MOSI / OC0A
|
7 | PB1 -- Pin 6 ---- MISO / OC0B / INT0 ---- my Button
|
8 | PB2 -- Pin 7 ---- SCK
|
9 | PB3 -- Pin 2 ---- CLKI
|
10 | PB4 -- Pin 3 ---------------------------- my LED
|
11 | PB5 -- Pin 1 ---- RESET
|
12 | ------------------------------------------------- */
|
13 | |
14 | #define F_CPU 1200000UL // 9.6MHz/8
|
15 | #include <avr/io.h> |
16 | #include <avr/interrupt.h> |
17 | #include <avr/sleep.h> |
18 | |
19 | int8_t a = 0; // flag |
20 | uint8_t k = 0; // timer overflow count |
21 | uint8_t tp = 20; // output pulse time period in seconds/4, (max 255 = 63.75s) |
22 | |
23 | ISR(INT0_vect) { |
24 | a = 1; |
25 | }
|
26 | |
27 | ISR(TIM0_OVF_vect) { |
28 | k++; |
29 | }
|
30 | |
31 | int main(void) { |
32 | |
33 | DDRB |= (1<<DDB4); // output ---------- pin 3 |
34 | PORTB &= ~(1<<PORTB4); // clear output bit |
35 | DDRB &= ~(1<<DDB1); // input ----------- pin 6 |
36 | PORTB |= (1<<PORTB1); // pullup |
37 | GIMSK |= (1<<INT0); // enable external interrupt on INT0 |
38 | TCCR0B |= ((1<<CS02) | (1<<CS00)); // prescaler/1024 (1200000/1024/256 = 4Hz, 0.25s) |
39 | TIMSK0 |= (1<<TOIE0); // enable timer overflow interrupt |
40 | set_sleep_mode(SLEEP_MODE_PWR_DOWN); |
41 | sei(); // enable interrupts |
42 | |
43 | while (1) { |
44 | if(a == 1) { |
45 | PORTB |= (1<<PORTB4); // set output bit |
46 | a = 0; |
47 | k = 0; |
48 | }
|
49 | if(k == tp) { |
50 | PORTB &= ~(1<<PORTB4); // clear output bit |
51 | a = 0; |
52 | k = 0; |
53 | sleep_enable(); |
54 | sleep_cpu(); |
55 | sleep_disable(); |
56 | }
|
57 | }
|
58 | return 0; |
59 | }
|