1 | #include <avr/io.h>
|
2 | #include <util/delay.h>
|
3 | #include <avr/eeprom.h>
|
4 | #include <avr/interrupt.h>
|
5 | #include <stdint.h>
|
6 |
|
7 | volatile int i = 0;
|
8 | volatile char MODE_VAL = 0;
|
9 | #define PWM_WS OCR1A //Pin Ausgang
|
10 | #define PWM_BL OCR1B
|
11 | #define LED_WS PB3
|
12 | #define LED_BL PB4
|
13 | #define DDR_IN DDRD
|
14 | #define PULLUP PORTD
|
15 | #define PIN_IN PIND
|
16 | #define MODE PD0
|
17 | #define UP PD1
|
18 | #define DOWN PD2
|
19 | #define PORT_IN PORTD
|
20 | #define DDR_OUT DDRB
|
21 | #define PORT_OUT PORTB
|
22 | #define LED_CHK PB7
|
23 |
|
24 | #ifndef EEMEM
|
25 | // alle Textstellen EEMEM im Quellcode durch __attribute__ ... ersetzen
|
26 | #define EEMEM __attribute__ ((section (".eeprom")))
|
27 | #endif
|
28 |
|
29 | uint16_t eeTOP_WS EEMEM;
|
30 | uint16_t eeTOP_BL EEMEM;
|
31 | uint16_t eePWM_WS EEMEM;
|
32 | uint16_t eePWM_BL EEMEM;
|
33 | uint16_t eeSPEED EEMEM;// = 1023; //eeTOP ist der Speicherbereich im EEPROM
|
34 | volatile uint16_t intTOP_WS;
|
35 | volatile uint16_t intTOP_BL;
|
36 | volatile uint16_t intPWM_WS;
|
37 | volatile uint16_t intPWM_BL;
|
38 | volatile uint16_t intSPEED;
|
39 |
|
40 |
|
41 | //------------ Taster entprellen ------------
|
42 | #define ALL_KEYS (1<<MODE | 1<<UP | 1<<DOWN)
|
43 |
|
44 | #define REPEAT_MASK (1<<UP | 1<<DOWN) // repeat: key1, key2
|
45 | #define REPEAT_START 50 // after 500ms
|
46 | #define REPEAT_NEXT 20 // every 200ms
|
47 | // every 200ms
|
48 |
|
49 | volatile uint8_t key_state; // debounced and inverted key state:
|
50 | // bit = 1: key pressed
|
51 | volatile uint8_t key_press; // key press detect
|
52 |
|
53 | volatile uint8_t key_rpt; // key long press and repeat
|
54 |
|
55 |
|
56 | ISR( TIMER0_OVF_vect ) // every 10ms
|
57 | {
|
58 | static uint8_t ct0, ct1, rpt;
|
59 | uint8_t i;
|
60 |
|
61 | TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5); // preload for 10ms
|
62 |
|
63 | i = key_state ^ ~PIN_IN; // key changed ?
|
64 | ct0 = ~( ct0 & i ); // reset or count ct0
|
65 | ct1 = ct0 ^ (ct1 & i); // reset or count ct1
|
66 | i &= ct0 & ct1; // count until roll over ?
|
67 | key_state ^= i; // then toggle debounced state
|
68 | key_press |= key_state & i; // 0->1: key press detect
|
69 |
|
70 | if( (key_state & REPEAT_MASK) == 0 ) // check repeat function
|
71 | rpt = REPEAT_START; // start delay
|
72 | if( --rpt == 0 ){
|
73 | rpt = REPEAT_NEXT; // repeat delay
|
74 | key_rpt |= key_state & REPEAT_MASK;
|
75 | }
|
76 | }
|
77 |
|
78 | ///////////////////////////////////////////////////////////////////
|
79 | //
|
80 | // check if a key has been pressed. Each pressed key is reported
|
81 | // only once
|
82 | //
|
83 | uint8_t get_key_press( uint8_t key_mask )
|
84 | {
|
85 | cli(); // read and clear atomic !
|
86 | key_mask &= key_press; // read key(s)
|
87 | key_press ^= key_mask; // clear key(s)
|
88 | sei();
|
89 | return key_mask;
|
90 | }
|
91 |
|
92 | ///////////////////////////////////////////////////////////////////
|
93 | //
|
94 | // check if a key has been pressed long enough such that the
|
95 | // key repeat functionality kicks in. After a small setup delay
|
96 | // the key is reported beeing pressed in subsequent calls
|
97 | // to this function. This simulates the user repeatedly
|
98 | // pressing and releasing the key.
|
99 | //
|
100 | uint8_t get_key_rpt( uint8_t key_mask )
|
101 | {
|
102 | cli(); // read and clear atomic !
|
103 | key_mask &= key_rpt; // read key(s)
|
104 | key_rpt ^= key_mask; // clear key(s)
|
105 | sei();
|
106 | return key_mask;
|
107 | }
|
108 |
|
109 | ///////////////////////////////////////////////////////////////////
|
110 | //
|
111 | uint8_t get_key_short( uint8_t key_mask )
|
112 | {
|
113 | cli(); // read key state and key press atomic !
|
114 | return get_key_press( ~key_state & key_mask );
|
115 | }
|
116 |
|
117 | ///////////////////////////////////////////////////////////////////
|
118 | //
|
119 | uint8_t get_key_long( uint8_t key_mask )
|
120 | {
|
121 | return get_key_press( get_key_rpt( key_mask ));
|
122 | }
|
123 |
|
124 |
|
125 |
|
126 | void pwm_init(void)
|
127 | {
|
128 | //http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#PWM_.28Pulsweitenmodulation.29
|
129 | //fast-pwm; clear on compare match, set at top
|
130 | TCCR1A |= (1<<WGM10) | (1<<WGM11) | (1<<WGM12) | (1<<COM1A1) | (1<<COM1A0) | (1<<COM1B1) | (1<<COM1B0);
|
131 | TCCR1B |= (1<<CS10);
|
132 | //OCR1A = pwm; //compare match
|
133 | }
|
134 |
|
135 | void debounce_init(void)
|
136 | {
|
137 | TCCR0A = (1<<CS02)|(1<<CS00); // divide by 1024; timer for decouncing
|
138 | TIMSK = 1<<TOIE0;
|
139 | }
|
140 |
|
141 | void init_io(void)
|
142 | {
|
143 | DDR_OUT |= (1<<LED_WS) | (1<<LED_BL) | (1<<LED_CHK);
|
144 | PORT_OUT |= (1<<LED_WS) | (1<<LED_BL) | (1<<LED_CHK);
|
145 | DDR_IN &=~ (1<<MODE) | (1<<UP) | (1<<DOWN);
|
146 | PULLUP |= (1<<MODE) | (1<<UP) | (1<<DOWN);
|
147 |
|
148 |
|
149 |
|
150 | }
|
151 | void flush(void)
|
152 | {
|
153 | for (i = 0; i < intTOP_WS; i++)
|
154 | {
|
155 | PWM_WS++;
|
156 | PWM_BL--;
|
157 | _delay_ms(6);
|
158 |
|
159 | }
|
160 |
|
161 | for (i = 0; i < intTOP_BL; i++)
|
162 | {
|
163 | PWM_WS--;
|
164 | PWM_BL++;
|
165 | _delay_ms(6);
|
166 |
|
167 | }
|
168 |
|
169 | }
|
170 |
|
171 | void main(void)
|
172 | {
|
173 | init_io();
|
174 | debounce_init();
|
175 | pwm_init();
|
176 | intTOP_WS = eeprom_read_word(&eeTOP_WS);
|
177 | intTOP_BL = eeprom_read_word(&eeTOP_BL);
|
178 | PWM_BL = intTOP_BL;
|
179 | sei();
|
180 | while(1)
|
181 | {
|
182 | if( get_key_press( 1<<MODE ) || get_key_rpt( 1<<MODE ))
|
183 |
|
184 | {
|
185 | PORT_OUT &=~ (1<<LED_CHK);
|
186 | intTOP_WS = 250;
|
187 | eeprom_write_word(&eeTOP_WS, intTOP_WS); // schreiben
|
188 | intTOP_WS = eeprom_read_word(&eeTOP_WS);
|
189 |
|
190 |
|
191 | intTOP_BL = 250;
|
192 | eeprom_write_word(&eeTOP_BL, intTOP_BL); // schreiben
|
193 | intTOP_BL = eeprom_read_word(&eeTOP_BL);
|
194 | PWM_BL = intTOP_BL;
|
195 | }
|
196 |
|
197 | // - Pwm in eprom ablegen und auf ocxn schalten
|
198 | /*if ( !(PIN_IN & (1<<MODE)) )
|
199 | {
|
200 | PORT_OUT &=~ (1<<LED_CHK);
|
201 | intTOP_WS = 250;
|
202 | eeprom_write_word(&eeTOP_WS, intTOP_WS); // schreiben
|
203 | intTOP_WS = eeprom_read_word(&eeTOP_WS);
|
204 |
|
205 |
|
206 | intTOP_BL = 250;
|
207 | eeprom_write_word(&eeTOP_BL, intTOP_BL); // schreiben
|
208 | intTOP_BL = eeprom_read_word(&eeTOP_BL);
|
209 | PWM_BL = intTOP_BL;
|
210 | }*/
|
211 |
|
212 |
|
213 |
|
214 |
|
215 | flush();
|
216 |
|
217 |
|
218 | }
|
219 |
|
220 |
|
221 |
|
222 |
|
223 |
|
224 | }
|