Taster abfragen, prellen

Gast #1596796
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
}
#1596839
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
#1596884
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
#1596960
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".

...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren