von
pille1990 (Gast)
13.02.2010 21:57
Hallo,
ich habe ein kleines Programm geschrieben, das per PWM RGB-LEDs dimmt
(atmega32). Nun will ich, dass man über Taster das ganze steuern kann.
Wird der „Stopptaster“ gedrückt, soll der Controller von ständig
wechselnden LED -Farben auf immer gleich bleibende Farben wechseln. Wird
der Taster nochmals gedrückt, wechseln die Farben wieder. Dann gibt es
noch einen „Modustaster“ ist dieser gedrückt worden, wird die Farbe der
LED s abhängig vom einem Poti am AD-Wandler gesteuert. Drückt man den
Taster noch mal, kommt man wieder in den „Wechselmodus“.
Die Frage ist jetz wie ich die Taster abfrage, weil diese ja immer
prellen. Mit externen Interrupts habe ich das ganze schon
probiert....das funktioniert nicht so richtig...durch das Prellen der
Taster wird die ISR mehrmals ausgeführt. Auf deutsch: Entweder brauche
ich eine vernünftige Tasterentprellung oder eine andere Software. Im
Anhang findet ihr das Programm.
Freue mich schon auf konstuktive Vorschläge...
Gruß
Pille
1 /**********************************************************************/
2 /************************Ambilight made by PiLLe***********************/
3 /******************************Version 12.0****************************/
4 /**********************************************************************/
5 /*Anschluss: */
6 /*OUT_RED: OCR0 (PB3) */
7 /*OUT_GREEN: OCR1A (PD5) */
8 /*OUT_BLUE: OCR2 (PD7) */
9 /*Stopptaster: PD2 (INT0) */
10 /*Modustaster PD3 (INT1) */
11 /*Poti: PA1 */
12 /*Stop-LED PA5 */
13 /*Durchlauf-LED: PA6 */
14 /*AD-Wandler-LED: PA7 */
15 /**********************************************************************/
16
17
18 /**********************************************************************/
19 //Includes
20 /**********************************************************************/
21
22 #include <avr/io.h>
23 #include <util/delay.h>
24 #include <avr/interrupt.h>
25
26 /**********************************************************************/
27 //Defines
28 /**********************************************************************/
29
30 #define OUT_RED OCR0
31 #define OUT_GREEN OCR1A
32 #define OUT_BLUE OCR2
33 #define INT0_vect _VECTOR(1)
34 #define INT1_vect _VECTOR(2)
35
36 //merker für stop
37 volatile uint8_t stop = 0x00 ;
38
39 //merker für modus
40 volatile uint8_t modus = 0x00 ;
41
42 /**********************************************************************/
43 //Interruptroutinen
44 /**********************************************************************/
45
46 //ISR für stoptaster
47 ISR ( INT0_vect )
48 {
49 //wenn taster schon gedrückt wurde bit löschen, sonst bit setzen
50 if ( stop == 0x01 )
51 {
52 stop = 0x00 ;
53
54 //stop led aussschalten
55 PORTA &= ~ ( 1 << PA5 );
56
57 //durchlauf led einschalten
58 PORTA |= ( 1 << PA6 );
59 }
60
61 else
62 {
63 stop = 0x01 ;
64
65 //stop led einschalten
66 PORTA |= ( 1 << PA5 );
67
68 //durchlauf led ausschalten
69 PORTA &= ~ ( 1 << PA6 );
70 }
71 }
72
73
74 //ISR für modustaster
75 ISR ( INT1_vect )
76 {
77 //wenn taster schon gedrückt wurde bit löschen, sonst bit setzen
78 if ( modus == 0x01 )
79 {
80 modus = 0x00 ;
81
82 //ad-wandler led ausschalten
83 PORTA &= ~ ( 1 << PA7 );
84
85 //durchlauf led einschalten
86 PORTA |= ( 1 << PA6 );
87
88 //stopptaste wieder aktivieren
89 GICR |= ( 1 << INT0 );
90 }
91
92 else
93 {
94 modus = 0x01 ;
95
96 //ad wandler led einschalten
97 PORTA |= ( 1 << PA7 );
98
99 //durchlauf led ausschalten
100 PORTA &= ~ ( 1 << PA6 );
101
102 //stopptaste deaktivieren
103 GICR &= ~ ( 1 << INT0 );
104 }
105 }
106
107 /**********************************************************************/
108 //Hauptprogramm
109 /**********************************************************************/
110
111 int main ()
112 {
113
114 //durchlauf led einschalten
115 PORTA |= ( 1 << PA6 );
116
117 /**********************************************************************/
118 //Variablen
119 /**********************************************************************/
120
121 //pwm array
122 uint8_t pwm_value [ 192 ] = { 0 , 21 , 41 , 59 , 76 , 91 , 105 , 117 , 129 , 139 , 149 , 158 , 166 , 174 , 181 , 187 ,
123 193 , 198 , 203 , 207 , 211 , 215 , 218 , 221 , 224 , 227 , 229 , 231 , 233 , 235 , 237 , 238 ,
124 240 , 241 , 242 , 243 , 244 , 245 , 246 , 247 , 247 , 248 , 249 , 249 , 250 , 250 , 251 , 251 ,
125 251 , 252 , 252 , 252 , 252 , 253 , 253 , 253 , 253 , 253 , 253 , 254 , 254 , 254 , 254 , 254 ,
126
127 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 ,
128 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 ,
129 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 ,
130 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 ,
131
132 255 , 254 , 254 , 254 , 254 , 254 , 253 , 253 , 253 , 253 , 253 , 253 , 252 , 252 , 252 , 252 ,
133 251 , 251 , 251 , 250 , 250 , 249 , 249 , 248 , 247 , 247 , 246 , 245 , 244 , 243 , 242 , 241 ,
134 240 , 238 , 237 , 235 , 233 , 231 , 229 , 227 , 224 , 221 , 218 , 215 , 211 , 207 , 203 , 198 ,
135 193 , 187 , 181 , 174 , 166 , 158 , 149 , 139 , 129 , 117 , 105 , 91 , 76 , 59 , 41 , 21 };
136
137 //zählvariablen
138 uint8_t value_red = 0 ;
139 uint8_t value_green = 0 ;
140 uint8_t value_blue = 0 ;
141
142 //wert für stehenden modus
143 uint8_t color_value = 0 ;
144
145 //geschwindigkeitsvariable
146 uint16_t speed ;
147
148 //geschwindigkeitsmultiplizierfaktor
149 uint8_t factor = 3 ;
150
151 //maximum der zählschritte (durch array festgelegt)
152 uint8_t maximum = 191 ;
153
154 /**********************************************************************/
155 //Interruptdefinition
156 /**********************************************************************/
157
158 //Interrupt konfigurieren fallenden flanke
159 MCUCR |= ( 1 << ISC00 ) | ( 1 << ISC01 );
160 MCUCR |= ( 1 << ISC10 ) | ( 1 << ISC11 );
161
162
163 //Interrupt aktivieren
164 GICR |= ( 1 << INT0 );
165 GICR |= ( 1 << INT1 );
166
167 /**********************************************************************/
168 //Ad-Wandlerdefinition
169 /**********************************************************************/
170
171 //adc enable
172 ADCSRA |= ( 1 << ADEN );
173
174 //messvorgang starten
175 ADCSRA |= ( 1 << ADSC );
176
177 //freerunning mode starten
178 ADCSRA |= ( 1 << ADATE );
179
180 //prescaler auf 62 khz
181 ADCSRA |= ( 1 << ADPS2 );
182
183 //AVCC als referenz nehmen
184 ADMUX |= ( 1 << REFS0 );
185
186 //kanal 1 auswählen
187 ADMUX |= ( 1 << MUX0 );
188
189 //ad-wandler auf 8bit stellen
190 ADMUX |= ( 1 << ADLAR );
191
192
193 /**********************************************************************/
194 //Timerdefinition
195 /**********************************************************************/
196
197 //prescaler einstellen
198 TCCR0 |= ( 1 << CS00 );
199
200 TCCR1B |= ( 1 << CS10 );
201
202 TCCR2 |= ( 1 << CS20 );
203
204
205 //timer auf fast pwm mode stellen
206 TCCR0 |= ( 1 << WGM00 );
207
208 TCCR1A |= ( 1 << WGM10 );
209 TCCR1B |= ( 1 << WGM12 );
210
211 TCCR2 |= ( 1 << WGM20 );
212
213
214 //invertierte pwm
215 TCCR0 |= ( 1 << COM00 );
216 TCCR0 |= ( 1 << COM01 );
217
218 TCCR1A |= ( 1 << COM1A0 ) | ( 1 << COM1A1 );
219 TCCR1A |= ( 1 << COM1B0 ) | ( 1 << COM1B1 );
220
221 TCCR2 |= ( 1 << COM20 );
222 TCCR2 |= ( 1 << COM21 );
223
224
225 //hiermit wird der gewünschte pwm wert eingestellt
226 OUT_RED = 0 ;
227
228 OUT_GREEN = 0 ;
229
230 OUT_BLUE = 0 ;
231
232
233 /**********************************************************************/
234 //Ausgänge definieren
235 /**********************************************************************/
236
237 //PD5 gehört zu timer1, PD7 zu timer2, PB3 gehört zu timer0, PA5-7 für Betriebszustandsleds
238 DDRD |= ( 1 << PD5 ) | ( 1 << PD7 );
239 DDRB |= ( 1 << PB3 );
240 DDRC |= ( 1 << PC0 );
241 DDRA |= ( 1 << PA5 ) | ( 1 << PA6 ) | ( 1 << PA7 );
242
243 //verschiebung festlegen
244 value_green = value_red + 64 ;
245 value_blue = value_red + 128 ;
246
247
248 //Interrupts erlauben
249 sei ();
250
251
252
253 /**********************************************************************/
254 //Hauptschleife
255 /**********************************************************************/
256
257 while ( 1 )
258 {
259
260 //wenn PD1 high ist in poti modus wechseln
261 if ( modus == 0x01 )
262 {
263
264 /**********************************************************************/
265 //Potimodus
266 /**********************************************************************/
267
268 //ad-wandlung in eine variable schreiben (8bit)
269 color_value = ADCH ;
270
271 //werte an die timer weitergeben
272 OUT_RED = pwm_value [ color_value ];
273
274 OUT_GREEN = pwm_value [ color_value + 64 ];
275
276 OUT_BLUE = pwm_value [ color_value + 128 ];
277
278 }
279
280 else
281 {
282
283 /**********************************************************************/
284 //Stehender Modus
285 /**********************************************************************/
286
287 if ( stop == 0x01 )
288 {
289 _delay_us ( 1 );
290 }
291
292 else
293 {
294
295 /**********************************************************************/
296 //Durchlaufmodus
297 /**********************************************************************/
298
299 //den ausgängen die werte zuweisen
300 OUT_RED = pwm_value [ value_red ];
301
302 OUT_GREEN = pwm_value [ value_green ];
303
304 OUT_BLUE = pwm_value [ value_blue ];
305
306 //ad-wandlung in speed laden
307 speed = ADCH ;
308
309 //warten bis das nächste mal die werte zugewiesen werden
310 _delay_ms ( speed * factor );
311
312
313 //zählvarialben hochzuählen und überprüfen ob sie voll sind, wenn ja auf 0 zurücksetzen
314 value_red ++ ;
315
316 value_green ++ ;
317
318 value_blue ++ ;
319
320 if ( value_red == maximum )
321 value_red = 0 ;
322
323 if ( value_green == maximum )
324 value_green = 0 ;
325
326 if ( value_blue == maximum )
327 value_blue = 0 ;
328
329 }
330 }
331
332 }
333
334
335 }
Das Thema wurde doch schon unzaehlige Male behandelt. Such mal nach
"entprellen" im Forum. Da kommen mindestens zwei Seiten voller
Ergebnisse.
Im Prinzip: Regelmaessig auf Tastendruck checken, wenn Taste nicht
gedrueckt, Counter zuruecksetzen, wenn Taste gedrueckt, weiter
regelmaessig checken und dabei Counter hochzaehlen, wenn Counter = ein
bestimmter Wert, Tastendruck erkannt.
Also schauen ob der Taster fuer X ms dauerhaft geschlossen war...
Volker
von
Werner (Gast)
13.02.2010 22:35
Warum meint eigentlich jeder Trottel, er könne sein dämliches
Programm direkt im Post präsentieren, ohne dafür den Dateianhang zu
bemühen?
Werner schrieb:
> Warum meint eigentlich jeder Trottel, er könne sein dämliches
> Programm direkt im Post präsentieren, ohne dafür den Dateianhang zu
> bemühen?
Wenn man vergisst das Forum vor dem Fragen auf eventuell vorhandene
Antworten zu durchsuchen, kann man auch schonmal das fettgedruckte
1 "Wichtige Regeln - erst lesen, dann posten!"
und das darauf folgende
1 "Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
uebersehen. Viele hier im Forum schaffen es aber nichtmal bis zu
1 Groß- und Kleinschreibung verwenden
und bekommen auch keinen Aerger... ;)
Volker
von
Werner (Gast)
13.02.2010 22:58
>Viele hier im Forum schaffen es aber nichtmal bis zu
>Groß- und Kleinschreibung verwenden
>und bekommen auch keinen Aerger... ;)
Ja, warum eigentlich nicht ;-)
Werner schrieb:
>>Viele hier im Forum schaffen es aber nichtmal bis zu
>>Groß- und Kleinschreibung verwenden
>
>>und bekommen auch keinen Aerger... ;)
>
> Ja, warum eigentlich nicht ;-)
Weil dann z.B. sofort wieder "Diskriminierung" geschrien wird, oder
"Hast wohl keine Argumente mehr und ziehst Dich an Kleinigkeiten hoch"
oder "Dressiere einen Hamster".
...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.