1 | /****************************************************************************/
|
2 | /* */
|
3 | /* Programm LED und Taster aktiv high */
|
4 | /* */
|
5 | /****************************************************************************/
|
6 |
|
7 | #ifndef F_CPU
|
8 | #define F_CPU 8000000 // processor clock frequency 8Mhz
|
9 | #warning kein F_CPU definiert
|
10 | #endif
|
11 |
|
12 | #include <stdint.h>
|
13 | #include <avr/io.h>
|
14 | #include <avr/interrupt.h>
|
15 | #include <inttypes.h>
|
16 |
|
17 | #define LED PB1 //Pin der LED
|
18 | #define PIN_Taster PINB
|
19 | #define Taster PB0
|
20 |
|
21 | // ----------------------------------------------------------------------------
|
22 | // Funktionsdeklarationen
|
23 | // ----------------------------------------------------------------------------
|
24 | void init(void);
|
25 | uint8_t get_key_press( uint8_t key_mask );
|
26 |
|
27 |
|
28 | // ----------------------------------------------------------------------------
|
29 | // globale Variablen für Interrupts (volatile)
|
30 | // ----------------------------------------------------------------------------
|
31 | volatile uint8_t key_state; // debounced and inverted key state:
|
32 | // bit = 1: key pressed
|
33 | volatile uint8_t key_press; // key press detect
|
34 | volatile unsigned short millisekunden = 0;
|
35 | volatile unsigned short entprellzeit = 0;
|
36 |
|
37 |
|
38 |
|
39 | //Timer2 Comapre Match Interrupt CTC
|
40 | ISR(TIMER2_COMP_vect) // every 1ms
|
41 | {
|
42 | millisekunden++; // wird für späteres pollen benötigt
|
43 | entprellzeit++;
|
44 | if (entprellzeit == 10){ // every 10ms
|
45 | static uint8_t ct0, ct1;
|
46 | uint8_t i;
|
47 |
|
48 | entprellzeit = 0; // Entprellzeit wieder zurücksetzen
|
49 |
|
50 | i = key_state ^ PIN_Taster; // key changed ?
|
51 | ct0 = ~( ct0 & i ); // reset or count ct0
|
52 | ct1 = ct0 ^ (ct1 & i); // reset or count ct1
|
53 | i &= ct0 & ct1; // count until roll over ?
|
54 | key_state ^= i; // then toggle debounced state
|
55 | key_press |= key_state & i; // 0->1: key press detect
|
56 |
|
57 | }
|
58 | }
|
59 |
|
60 | //Das Hauptprogramm
|
61 | int main()
|
62 | {
|
63 |
|
64 | TCCR2 = (1<<CS22) | (1 << WGM21); // Prescaler 64, CTC Clear on Compare Match
|
65 | OCR2 = 124; // jede 1ms tritt ein Compare Match Interrupt auf
|
66 | TIMSK |= (1<<OCIE2); // Timer Compare Match Enable
|
67 |
|
68 | DDRB = 0x00; //Datenrichtungsregister zunächst alle Eingang
|
69 | DDRB |= (1 << DDB1); //PB1 als Ausgang schalten für LED
|
70 | PORTB = (1 << PB1); //LED aus
|
71 |
|
72 | sei();
|
73 |
|
74 | while(1)
|
75 |
|
76 |
|
77 | //Zustand des Tasters abfragen mit Entprellfunktion
|
78 | if (get_key_press( 1<<Taster )){
|
79 |
|
80 | if (!(PINB & (1<<LED))){ //LED war an
|
81 | PORTB |= (1 << LED); //LED ausschalten
|
82 |
|
83 | }
|
84 |
|
85 | else {
|
86 | PORTB &=~ (1 << LED); //LED anschalten
|
87 | }
|
88 | }
|
89 |
|
90 | }
|
91 |
|
92 | // Funktionen
|
93 | ///////////////////////////////////////////////////////////////////
|
94 | // by Peter Danegger
|
95 | // check if a key has been pressed. Each pressed key is reported
|
96 | // only once
|
97 | ///////////////////////////////////////////////////////////////////
|
98 | uint8_t get_key_press( uint8_t key_mask )
|
99 | {
|
100 | cli(); // read and clear atomic !
|
101 | key_mask &= key_press; // read key(s)
|
102 | key_press ^= key_mask; // clear key(s)
|
103 | sei();
|
104 | return key_mask;
|
105 | }
|