www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Taster abfragen, prellen


Autor: pille1990 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
/**********************************************************************/
/************************Ambilight made by PiLLe***********************/
/******************************Version 12.0****************************/
/**********************************************************************/
/*Anschluss:                              */
/*OUT_RED:      OCR0 (PB3)                      */
/*OUT_GREEN:    OCR1A (PD5)                      */
/*OUT_BLUE:      OCR2 (PD7)                      */
/*Stopptaster:    PD2 (INT0)                      */
/*Modustaster    PD3  (INT1)                      */
/*Poti:        PA1                          */
/*Stop-LED      PA5                          */  
/*Durchlauf-LED:  PA6                          */  
/*AD-Wandler-LED:  PA7                          */    
/**********************************************************************/


/**********************************************************************/
//Includes
/**********************************************************************/

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

/**********************************************************************/
//Defines
/**********************************************************************/

#define OUT_RED       OCR0
#define OUT_GREEN       OCR1A
#define OUT_BLUE       OCR2
#define INT0_vect      _VECTOR(1)
#define INT1_vect      _VECTOR(2)

//merker für stop
volatile uint8_t stop = 0x00;

//merker für modus
volatile uint8_t modus = 0x00;

/**********************************************************************/
//Interruptroutinen
/**********************************************************************/
    
//ISR für stoptaster    
ISR(INT0_vect)
  {  
  //wenn taster schon gedrückt wurde bit löschen, sonst bit setzen
  if(stop == 0x01)
    {
    stop = 0x00;

    //stop led aussschalten
    PORTA &= ~ (1 << PA5);

    //durchlauf led einschalten
    PORTA |= (1 << PA6);
    }

  else
    {
    stop = 0x01;

    //stop led einschalten
    PORTA |= (1 << PA5);

    //durchlauf led ausschalten
    PORTA &= ~ (1 << PA6);
    }
  }


//ISR für modustaster
ISR(INT1_vect)
  {
  //wenn taster schon gedrückt wurde bit löschen, sonst bit setzen
  if(modus == 0x01)
    {
    modus = 0x00;

    //ad-wandler led ausschalten
    PORTA &= ~ (1 << PA7);

    //durchlauf led einschalten
    PORTA |= (1 << PA6);

    //stopptaste wieder aktivieren
    GICR |= (1 << INT0);
    }

  else
    {
    modus = 0x01;
    
    //ad wandler led einschalten
    PORTA |= (1 << PA7);

    //durchlauf led ausschalten
    PORTA &= ~ (1 << PA6);

    //stopptaste deaktivieren
    GICR &= ~(1 << INT0);
    }
  }
  
/**********************************************************************/
//Hauptprogramm
/**********************************************************************/
         
int main()
{

//durchlauf led einschalten
PORTA |= (1 << PA6);

/**********************************************************************/
//Variablen
/**********************************************************************/

//pwm array
uint8_t pwm_value[192] =  { 0,   21,  41,  59,  76,  91,  105, 117, 129, 139, 149, 158, 166, 174, 181, 187, 
            193, 198, 203, 207, 211, 215, 218, 221, 224, 227, 229, 231, 233, 235, 237, 238, 
            240, 241, 242, 243, 244, 245, 246, 247, 247, 248, 249, 249, 250, 250, 251, 251,
            251, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, 254, 254, 254, 254, 254, 

            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
      
            255, 254, 254, 254, 254, 254, 253, 253, 253, 253, 253, 253, 252, 252, 252, 252, 
            251, 251, 251, 250, 250, 249, 249, 248, 247, 247, 246, 245, 244, 243, 242, 241,
            240, 238, 237, 235, 233, 231, 229, 227, 224, 221, 218, 215, 211, 207, 203, 198,
            193, 187, 181, 174, 166, 158, 149, 139, 129, 117, 105, 91,  76,  59,  41,  21};

  //zählvariablen
  uint8_t value_red = 0;
  uint8_t value_green = 0;
  uint8_t value_blue = 0;

  //wert für stehenden modus
  uint8_t color_value = 0;

  //geschwindigkeitsvariable
  uint16_t speed;

  //geschwindigkeitsmultiplizierfaktor
  uint8_t factor = 3;

  //maximum der zählschritte (durch array festgelegt)
  uint8_t maximum = 191;

/**********************************************************************/
//Interruptdefinition
/**********************************************************************/

  //Interrupt konfigurieren fallenden flanke
  MCUCR |= (1 << ISC00) | (1 << ISC01);
  MCUCR |= (1 << ISC10) | (1 << ISC11);


  //Interrupt aktivieren
  GICR |= (1 << INT0);
  GICR |= (1 << INT1);

/**********************************************************************/
//Ad-Wandlerdefinition
/**********************************************************************/

  //adc enable
  ADCSRA |= (1 << ADEN);

  //messvorgang starten
  ADCSRA |= (1 << ADSC);

  //freerunning mode starten
  ADCSRA |= (1 << ADATE);

  //prescaler auf 62 khz
  ADCSRA |= (1 << ADPS2);

  //AVCC als referenz nehmen
  ADMUX |= (1 << REFS0);

  //kanal 1 auswählen
  ADMUX |= (1 << MUX0);

  //ad-wandler auf 8bit stellen
  ADMUX |= (1 << ADLAR);


/**********************************************************************/
//Timerdefinition
/**********************************************************************/

  //prescaler einstellen
  TCCR0 |= (1 << CS00);

  TCCR1B |= (1 << CS10);
  
  TCCR2 |= (1 << CS20);


  //timer auf fast pwm mode stellen
  TCCR0 |=  (1 << WGM00);

  TCCR1A |= (1 << WGM10);
  TCCR1B |= (1 << WGM12);

  TCCR2 |= (1 << WGM20);


  //invertierte pwm
  TCCR0 |= (1 << COM00);
  TCCR0 |= (1 << COM01);

  TCCR1A |= (1 << COM1A0) | (1 << COM1A1);  
  TCCR1A |= (1 << COM1B0) | (1 << COM1B1);
  
  TCCR2 |= (1 << COM20);
  TCCR2 |= (1 << COM21);


  //hiermit wird der gewünschte pwm wert eingestellt
  OUT_RED = 0;

  OUT_GREEN = 0;

  OUT_BLUE = 0;


/**********************************************************************/
//Ausgänge definieren
/**********************************************************************/  
  
  //PD5 gehört zu timer1, PD7 zu timer2, PB3 gehört zu timer0, PA5-7 für Betriebszustandsleds
  DDRD |= (1 << PD5) | (1 << PD7);
  DDRB |= (1 << PB3);
  DDRC |= (1 << PC0);
  DDRA |= (1 << PA5) | (1 << PA6) | (1 << PA7);

  //verschiebung festlegen
  value_green = value_red + 64;
  value_blue = value_red + 128;


  //Interrupts erlauben
  sei();

  

/**********************************************************************/
//Hauptschleife
/**********************************************************************/

  while(1)
  {

    //wenn PD1 high ist in poti modus wechseln
    if(modus == 0x01)
    {

/**********************************************************************/
//Potimodus
/**********************************************************************/
    
      //ad-wandlung in eine variable schreiben (8bit)
      color_value = ADCH;

      //werte an die timer weitergeben
      OUT_RED = pwm_value[color_value];

      OUT_GREEN = pwm_value[color_value + 64];

      OUT_BLUE = pwm_value[color_value + 128];

    }

    else
    {
    
/**********************************************************************/
//Stehender Modus
/**********************************************************************/
  
      if(stop == 0x01)
        {
        _delay_us(1);
        }

      else
        {

/**********************************************************************/
//Durchlaufmodus
/**********************************************************************/

        //den ausgängen die werte zuweisen
        OUT_RED = pwm_value[value_red];

        OUT_GREEN = pwm_value[value_green];
  
        OUT_BLUE = pwm_value[value_blue];

        //ad-wandlung in speed laden
        speed = ADCH;

        //warten bis das nächste mal die werte zugewiesen werden
        _delay_ms(speed*factor);
  

        //zählvarialben hochzuählen und überprüfen ob sie voll sind, wenn ja auf 0 zurücksetzen
        value_red++;
  
        value_green++;

        value_blue++;

        if(value_red == maximum)
        value_red = 0;

        if(value_green == maximum)
        value_green = 0;

        if(value_blue == maximum)
        value_blue = 0;
        
        }
    }

  }


}


Autor: Volker Schulz (volkerschulz)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Volker Schulz (volkerschulz)
Datum:

Bewertung
0 lesenswert
nicht 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
 "Wichtige Regeln - erst lesen, dann posten!"

und das darauf folgende
 "Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

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

und bekommen auch keinen Aerger... ;)


Volker

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
;-)

Entprellung

...

Autor: Werner (Gast)
Datum:

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

>und bekommen auch keinen Aerger... ;)

Ja, warum eigentlich nicht ;-)

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.