1 | // Tasten Entprellroutine von Peter Dannegger: danni@specs.de
|
2 |
|
3 | #include <stdio.h>
|
4 | #include <avr/io.h>
|
5 | #include <avr/interrupt.h>
|
6 |
|
7 | #define Taste_DDR DDRB
|
8 | #define Taste_PIN PINB
|
9 | #define Taste_PORT PORTB
|
10 | #define Taste1 PB4
|
11 | #define Taste2 PB3
|
12 |
|
13 | #define Led_DDR DDRB
|
14 | #define Led_PORT PORTB
|
15 | #define Led1 PB2
|
16 | #define Led2 PB1
|
17 | #define Led3 PB0
|
18 |
|
19 | #define KEY_DDR Taste_DDR
|
20 | #define KEY_PORT Taste_PORT
|
21 | #define KEY_PIN Taste_PIN
|
22 | #define KEY0 Taste1
|
23 | #define KEY1 Taste2
|
24 | #define ALL_KEYS (1<<KEY0 | 1<<KEY1)
|
25 |
|
26 | #define Led1_an Led_PORT &= ~(1<<Led1)
|
27 | #define Led1_aus Led_PORT |= (1<<Led1)
|
28 | #define Led2_an Led_PORT &= ~(1<<Led2)
|
29 | #define Led2_aus Led_PORT |= (1<<Led2)
|
30 | #define Led3_an Led_PORT &= ~(1<<Led3)
|
31 | #define Led3_aus Led_PORT |= (1<<Led3)
|
32 |
|
33 | #define Timer0_Reload 255 - 43 // 1,1 ms bei 11,0592 MHz
|
34 |
|
35 | #define max_Buffer_len 3 // max. 3 Tasten speichern
|
36 |
|
37 | uint8_t Buffer[max_Buffer_len]; // Buffer für Tasten
|
38 |
|
39 | //GPIOR sollte schneller sein als volatile auf Ram, ist das so ?????? Ich denke ja. Muß ich noch prüfen !!!!!!
|
40 |
|
41 | #define Zeiger GPIOR0 // Zeiger für Bufferposition
|
42 | #define Zeit GPIOR1 // Zeitzähler
|
43 | #define Zeit_mul GPIOR2 // Zeitmultiplikator für Interrupt
|
44 |
|
45 | volatile uint8_t Zeit_Entprellen;
|
46 | volatile uint8_t key_state; // debounced and inverted key state:
|
47 | volatile uint8_t key_press; // key press detect
|
48 |
|
49 |
|
50 | uint8_t get_key_press( uint8_t key_mask ){
|
51 | cli(); // read and clear atomic !
|
52 | key_mask &= key_press; // read key(s)
|
53 | key_press ^= key_mask; // clear key(s)
|
54 | sei();
|
55 | return key_mask;
|
56 | }
|
57 |
|
58 |
|
59 |
|
60 | ISR(TIMER0_OVF_vect){ // Timer0 Overflow alle 1,1 ms, 1,1 ms ist fest da
|
61 | // noch für andere Sachen gebraucht, leider !!!!
|
62 | static uint8_t ct0, ct1;
|
63 | uint8_t i;
|
64 |
|
65 | TCNT0 = Timer0_Reload; // Reloadwert laden
|
66 |
|
67 | if (Zeit_Entprellen > 10){ // alle 10 ms x 1,1 ms = 11 ms
|
68 | i = key_state ^ ~KEY_PIN; // key changed ?
|
69 | ct0 = ~( ct0 & i ); // reset or count ct0
|
70 | ct1 = ct0 ^ (ct1 & i); // reset or count ct1
|
71 | i &= ct0 & ct1; // count until roll over ?
|
72 | key_state ^= i; // then toggle debounced state
|
73 | key_press |= key_state & i; // 0->1: key press detect
|
74 | Zeit_Entprellen = 0; // Entprellmultiplikator zurücksetzen
|
75 | }
|
76 | if (Zeit_mul > 90){ // alle 91 ms x 1,1 ms = 100,1 ms
|
77 | Zeit++; // Zeit in 1/10 sec weiterzählen
|
78 | Zeit_mul = 0; // Zeitmultiplikator zurücksetzten
|
79 | }
|
80 | }
|
81 |
|
82 | void Buffer_Init(void){
|
83 | Zeiger = 0; // Bufferzeiger auf Anfang
|
84 | Buffer[0] = 0; // Buffer löschen
|
85 | Buffer[1] = 0; // Buffer löschen
|
86 | Buffer[2] = 0; // Buffer löschen
|
87 | }
|
88 |
|
89 | inline void Init(void){
|
90 | // Tasten
|
91 | Taste_DDR &= ~(1<<Taste1)|(1<<Taste2); // Taste1 & Taste2 Eingang
|
92 | Taste_PORT |= (1<<Taste1)|(1<<Taste2); // Taste1 & Taste2 Pullup an
|
93 | // Led
|
94 | Led_DDR |= (1<<Led1)|(1<<Led2)|(1<<Led3); // Led1 & Led2 & Led3 Ausgang
|
95 | Led_PORT |= (1<<Led1)|(1<<Led2)|(1<<Led3); // Led1 & Led2 & Led3 aus
|
96 | // Timer 0
|
97 | TCCR0A = 0; // Timer Normal Mode
|
98 | TCCR0B = (1<<CS02); // clkI/O / 256 (From prescaler)
|
99 | TIMSK |= (1<<TOIE0); // Timer/Counter0 Overflow Interrupt an
|
100 | // Buffer
|
101 | Buffer_Init(); // Bufferspeicher initialisieren
|
102 | }
|
103 |
|
104 | int main(void){
|
105 | Init(); // alles Initialisieren
|
106 | sei(); // Interrupt Global ein
|
107 | while(1){ // Endlosschleife
|
108 |
|
109 | if (Zeit > 30){ // wenn ca. 30 1/10 sec = 3 sec um sind
|
110 | Buffer_Init(); // Bufferspeicher initialisieren
|
111 | }
|
112 |
|
113 | if(get_key_press(1<<Taste1)){ // ist Taste1 gedrückt?
|
114 | if (Zeiger == 0){ // erste Taste gedrückt
|
115 | Zeit = 0; // Zeit zurücksetzen
|
116 | }
|
117 | if (Zeiger < max_Buffer_len - 1){ // wenn noch keine 3 Tasten gespeichert sind
|
118 | Buffer[Zeiger] = 1; // Tastendruck merken
|
119 | Zeiger++; // Zeiger weitersetzen
|
120 | }
|
121 | else{ // es sind schon 3 Tasten gespeichert
|
122 | Buffer[0] = Buffer[1]; // Bufferdaten Byteweise 1x links schieben, Byte 1
|
123 | Buffer[1] = Buffer[2]; // Bufferdaten Byteweise 1x links schieben, Byte 2
|
124 | Buffer[2] = 1; // Tastendruck in Byte 2 merken
|
125 | }
|
126 | }
|
127 | else if(get_key_press(1<<Taste2)){ // ist Taste2 gedrückt?
|
128 | if (Zeiger == 0){ // erste Taste gedrückt
|
129 | Zeit = 0; // Zeit zurücksetzen
|
130 | }
|
131 | if (Zeiger < max_Buffer_len - 1){ // wenn noch keine 3 Tasten gespeichert sind
|
132 | Buffer[Zeiger] = 2; // Tastendruck merken
|
133 | Zeiger++; // Zeiger weitersetzen
|
134 | }
|
135 | else{ // es sind schon 3 Tasten gespeichert
|
136 | Buffer[0] = Buffer[1]; // Bufferdaten Byteweise 1x links schieben, Byte 1
|
137 | Buffer[1] = Buffer[2]; // Bufferdaten Byteweise 1x links schieben, Byte 2
|
138 | Buffer[2] = 2; // Tastendruck in Byte 2 merken
|
139 | }
|
140 | }
|
141 |
|
142 | if (Buffer[0] == 1 && Buffer[1] == 1 && Buffer[2] == 1){// gedrückt Taste1 + Taste1 + Taste1
|
143 | Led1_an;
|
144 | Led2_aus;
|
145 | Led3_aus;
|
146 | Buffer_Init(); // Bufferspeicher initialisieren
|
147 | }
|
148 | if (Buffer[0] == 1 && Buffer[1] == 1 && Buffer[2] == 2){// gedrückt Taste1 + Taste1 + Taste2
|
149 | Led1_aus;
|
150 | Led2_an;
|
151 | Led3_aus;
|
152 | Buffer_Init(); // Bufferspeicher initialisieren
|
153 | }
|
154 | if (Buffer[0] == 1 && Buffer[1] == 2 && Buffer[2] == 1){// gedrückt Taste1 + Taste2 + Taste1
|
155 | Led1_aus;
|
156 | Led2_aus;
|
157 | Led3_an;
|
158 | Buffer_Init(); // Bufferspeicher initialisieren
|
159 | }
|
160 | }
|
161 | }
|