Forum: Mikrocontroller und Digitale Elektronik Entprelllung


von Mathias K. (underworldgamer)


Lesenswert?

Hallo


Wenn ich diesen Code simuliere mit AVR 4.12

------------------------------------

#include <avr/io.h>
#include <inttypes.h>
#ifndef F_CPU
#define F_CPU 1000000UL     /* Quarz mit 1 Mhz  */
#endif
#include <avr/delay.h>      /* definiert _delay_ms() ab avr-libc Version 
1.2.0 */
#include <util/delay.h>     /* in der aktuellen Version in util/ */


/* Einfache Funktion zum Entprellen eines Tasters */

inline uint8_t debounce(volatile uint8_t *port, uint8_t pin)
{
    if ( ! (*port & (1 << pin)) )
    {
        /* Pin wurde auf Masse gezogen, 100ms warten   */
        _delay_ms(100);
        if ( *port & (1 << pin) )
        {
            /* Anwender Zeit zum Loslassen des Tasters geben */
            _delay_ms(100);
            return 1;
        }
    }
    return 0;
}

int main(void)
{
    DDRB &= ~( 1 << PB0 );                 /* PIN PB0 auf Eingang 
(Taster)            */
    PORTB |= ( 1 << PB0 );                 /* Pullup-Widerstand 
aktivieren            */

    if (debounce(&PINB, PB0))             /* Falls Taster an PIN PB0 
gedrueckt..    */
        PORTD = PIND ^ ( 1 << PD7 );  /* ..LED an Port PD7 an-
                                   bzw. ausschalten */
--------------------------------------------------------------

Springt er immer am Ende hier hin passt das ?????

000006C4:   CFFF        RJMP    PC-0x0000        Relative jump


mfg Mathias Koch

von Uhu U. (uhu)


Lesenswert?

Leider hast Du das Ende Deiner main nicht mit gepostet.

Was macht die denn nach dem

   if (debounce(&PINB, PB0)) ...

Wenn Du sie verläßt, dann rast das Programm natürlich ins Nirwana. Main 
muß in einer unendlichen Schleife enden.

von Falk (Gast)


Lesenswert?

@ Uhu Uhuhu

>Wenn Du sie verläßt, dann rast das Programm natürlich ins Nirwana. Main
>muß in einer unendlichen Schleife enden.

Auch so ne Urban Legend. Ich weiss jetzt zwar nicht wie es beim AVR+GCC 
aussieht, aber z.B. beim M16C und original Renesas Compiler wird main 
auch nur als Funktion aufgerufen. Wird main wieder verlassen läuft der 
Prozessor in eine Endlosschleife. Nix Nirvana.

MfG
Falk




von Mathias K. (underworldgamer)


Lesenswert?

Hab mal nen Code geschrieben
wie kann ich es optiermieren das es schneller geht

..........................

/* Einfache Funktion zum Entprellen eines Tasters */

inline uint8_t debounce(volatile uint8_t *port, uint8_t pin)
{
    if ( ! (*port & (1 << pin)) )
    {
        /* Pin wurde auf Masse gezogen, 100ms warten   */
        _delay_ms(100);
        if ( *port & (1 << pin) )
        {
            /* Anwender Zeit zum Loslassen des Tasters geben */
            _delay_ms(100);
            return 1;
        }
    }
    return 0;
}



//////////////////////////////////////////////////////////////

int main(void)
{

  uart_init();
  DDRC =0x00;                 /* PIN PB0-PB7 auf Eingang (Taster) 
*/
    //DDRB &=~0x03;

  for(;;)
  {


      if (debounce(&PINC, PC0))
    {
          uart_putc(0x01);
    }

    if (debounce(&PINC, PC1))
    {
          uart_putc(0x02);
    }

    if (debounce(&PINC, PC2))
     {
          uart_putc(0x03);
    }

    if (debounce(&PINC, PC3))
{
          uart_putc(0x04);
    }

    if (debounce(&PINB, PB0))
 {
          uart_putc(0x05);
    }

    if (debounce(&PINB, PB1))
{
          uart_putc(0x06);
    }

    if (debounce(&PINB, PB2))
    {
          uart_putc(0x07);
    }

    }
}

.............................

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Code der auf Warteschleifen basiert auf Geschwindigkeit zu optimieren 
ist widersinnig. Du musst erst mal die Warteschleifen loswerden, z.B. 
indem du stattdessen einen Timer-Interrupt verwendet. Siehe Artikel 
Entprellung.

von Falk (Gast)


Lesenswert?

@  Andreas Schwarz

>Code der auf Warteschleifen basiert auf Geschwindigkeit zu optimieren
>ist widersinnig. Du musst erst mal die Warteschleifen loswerden, z.B.
>indem du stattdessen einen Timer-Interrupt verwendet. Siehe Artikel
>Entprellung.

Ersten das, und zweitens solltest du in er Routine Debounce ALLE Tasten 
gleichzeitig lesen und verarbeiten. Dann musst du nur einmal warten, 
wobei 100ms arg konservativ sind. So lange prellt keine Taste (Es sei 
denn sie ist kaputt) 10ms sollte reichen.

MfG
Falk


von Hannes L. (hannes)


Lesenswert?

Anstatt zu warten (auf der Stelle treten und nixtun, bis etwas 
passiert) kann man auch zyklisch vorbei schaun und wieder verschwinden 
und sich wichtigeren Dingen widmen, falls an den Tasten nix passiert 
ist.

Die Tastenentprellung sollte also als zyklischer Job programmiert werden 
und im Hintergrund laufen. Siehe auch PeDas Bulletproof-Entprellung in 
der Codesammlung bzw im Tutorial.

...

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.