1 | #include <util/delay.h>
|
2 | #include <stdint.h>
|
3 | #include <avr/io.h>
|
4 | #include <avr/wdt.h>
|
5 | #include <avr/interrupt.h>
|
6 | #include <avr/power.h>
|
7 | #include <avr/sleep.h>
|
8 |
|
9 | #if defined (__AVR_ATmega168__) || defined (__AVR_ATmega168P__)
|
10 | #define F_CPU 1000000UL
|
11 | #define TIM0_COMPA_vect TIMER0_COMPA_vect
|
12 | #define GIMSK PCICR
|
13 | #define PCIE PCIE0
|
14 | #define PCMSK PCMSK0
|
15 | #endif
|
16 |
|
17 | // PB0 - Switch (Input)
|
18 | // PB1 - NC (Output)
|
19 | // PB2 - NC (Output)
|
20 | // PB3 - NC (Output)
|
21 | // PB4 - Out (Output)
|
22 | // PB5 - NC (Output)
|
23 |
|
24 | #define SWITCH PB0
|
25 | #define SWITCH_ON ( !(PINB & (1 << SWITCH)) )
|
26 | #define SWITCH_OFF ( PINB & (1 << SWITCH) )
|
27 |
|
28 | #define OUT PB4
|
29 | #define OUT_ON PORTB |= (1 << OUT)
|
30 | #define OUT_OFF PORTB &= ~(1 << OUT)
|
31 | #define OUT_TOGGLE PORTB ^= (1 << OUT)
|
32 |
|
33 | #define MIN_PULSE_LEN 20
|
34 | #define MAX_PULSE_LEN1 200 // 250 debug
|
35 | #define MAX_PULSE_LEN2 250
|
36 | #define MAX_EVENT_LEN 500
|
37 |
|
38 | /*
|
39 | ATtiny13a
|
40 | ----
|
41 | PB5/Reset 1 -| |- 8 Vcc
|
42 | PB3 2 -| |- 7 PB2
|
43 | Out - PB4 3 -| |- 6 PB1
|
44 | GND 4 -|____|- 5 PB0 - Switch
|
45 |
|
46 |
|
47 | ATmega168P
|
48 | ----
|
49 | PC6/Reset 1 -| |- 28 PC5
|
50 | PD0/RxD 2 -| |- 27 PC4
|
51 | PD1/TxD 3 -| |- 26 PC3
|
52 | PD2 4 -| |- 25 PC2
|
53 | PD3 5 -| |- 24 PC1
|
54 | PD4 6 -| |- 23 PC0
|
55 | Vcc 7 -| |- 22 GND
|
56 | GND 8 -| |- 21 ARef
|
57 | PB6 9 -| |- 20 AVcc
|
58 | PB7 10 -| |- 19 PB5
|
59 | PD5 11 -| |- 18 PB4 - Out
|
60 | PD6 12 -| |- 17 PB3
|
61 | PD7 13 -| |- 16 PB2
|
62 | Switch - PB0 14 -|____|- 15 PB1
|
63 |
|
64 | */
|
65 |
|
66 | uint8_t flag0;
|
67 | uint8_t flag1;
|
68 | uint8_t flag2;
|
69 |
|
70 | uint16_t timer1;
|
71 | uint16_t timer2;
|
72 | uint16_t timer3;
|
73 |
|
74 | //**************************************************************************
|
75 |
|
76 | ISR(TIM0_COMPA_vect)
|
77 | {
|
78 | // Beginn des ersten Klicks
|
79 | if (SWITCH_ON && !flag1)
|
80 | {
|
81 | flag0 = 1; // Beginn des ersten Klicks erkannt
|
82 | timer1++; // Zähler für die Länge des ersten Klicks
|
83 | }
|
84 |
|
85 | if (flag0)
|
86 | {
|
87 | timer3++; // Zähler für die Gesamtlänge
|
88 | }
|
89 |
|
90 | // Ende des ersten Klicks
|
91 | if (SWITCH_OFF && !flag1 && (timer1 > MIN_PULSE_LEN) && (timer1 < MAX_PULSE_LEN1))
|
92 | {
|
93 | flag1 = 1; //Ende des ersten Klicks erkannt
|
94 | }
|
95 |
|
96 | // Beginn des zweiten Klicks
|
97 | if (SWITCH_ON && flag1)
|
98 | {
|
99 | flag2 = 1; // Beginn des zweiten Klicks erkannt
|
100 | timer2++; // Zähler für die Länge des zweiten Klicks
|
101 | }
|
102 |
|
103 | // Ende des zweiten Klicks
|
104 | if (SWITCH_OFF && flag1 && flag2 && (timer2 > MIN_PULSE_LEN) && (timer2 < MAX_PULSE_LEN2) && (timer3 < MAX_EVENT_LEN))
|
105 | {
|
106 | OUT_TOGGLE;
|
107 |
|
108 | flag0 = flag1 = flag2 = 0;
|
109 | timer1 = timer2 = timer3 = 0;
|
110 | }
|
111 |
|
112 | // Überprüfen auf Überlauf
|
113 | if (SWITCH_OFF && (timer3 >= MAX_EVENT_LEN))
|
114 | {
|
115 | flag0 = flag1 = flag2 = 0;
|
116 | timer1 = timer2 = timer3 = 0;
|
117 | }
|
118 | }
|
119 |
|
120 | //**************************************************************************
|
121 |
|
122 | void Timer0_Init(void)
|
123 | {
|
124 | TCCR0A = (1 << WGM00);
|
125 | TCCR0B = (0 << CS02) | (1 << CS01) | (1 << CS00); // prescaler 64
|
126 | OCR0A = (uint8_t)(F_CPU / (64.0 * 1e-3)); // 1 ms
|
127 | TIMSK0 = (1 << OCIE0A); // Interrupt für OCR aktivieren
|
128 | }
|
129 |
|
130 | //**************************************************************************
|
131 |
|
132 | int main(void)
|
133 | { GIMSK |= (1<<PCINT0);
|
134 | PORTB = 0;
|
135 | // Ausgänge definieren
|
136 | DDRB = (1 << DDB5) | (1 << DDB4) | (1 << DDB3) | (1 << DDB2) | (1 << DDB1);
|
137 |
|
138 | #if defined (__AVR_ATtiny13A__) || defined (__AVR_ATmega168__) || defined (__AVR_ATmega168P__)
|
139 | power_adc_disable();
|
140 | #endif
|
141 |
|
142 | flag0 = 0;
|
143 | flag1 = 0;
|
144 | flag2 = 0;
|
145 |
|
146 | timer1 = 0;
|
147 | timer2 = 0;
|
148 | timer3 = 0;
|
149 |
|
150 | Timer0_Init();
|
151 |
|
152 | sei(); // Interrupts aktivieren
|
153 |
|
154 | for(;;)
|
155 | {
|
156 | set_sleep_mode(SLEEP_MODE_IDLE);
|
157 | sleep_mode();
|
158 | }
|
159 |
|
160 | return 0; //nie erreicht
|
161 | }
|