Forum: Mikrocontroller und Digitale Elektronik Taster abfragen, prellen


von pille1990 (Gast)


Lesenswert?

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 
LEDs 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
}

von Volker S. (volkerschulz)


Lesenswert?

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)


Lesenswert?

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?

von Volker S. (volkerschulz)


Lesenswert?

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 Hannes L. (hannes)


Lesenswert?

;-)

Entprellung

...

von Werner (Gast)


Lesenswert?

>Viele hier im Forum schaffen es aber nichtmal bis zu
>Groß- und Kleinschreibung verwenden

>und bekommen auch keinen Aerger... ;)

Ja, warum eigentlich nicht ;-)

von Hannes L. (hannes)


Lesenswert?

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.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.