Forum: Mikrocontroller und Digitale Elektronik Frage zum Debounce Makro für Anfänger


von al3ko (Gast)


Lesenswert?

Hi,

Ich verwende das Debounce Makro für Anfänger von Peter D.

http://www.mikrocontroller.net/articles/Entprellung#Debounce-Makro_von_Peter_Dannegger


Gleichzeitig habe ich einen Taster (low-aktiv) an PD5 meines Atmega8 
angeschlossen und möchte einen Counter programmieren, der den jeweiligen 
Zählerstand auf dem LCD anzeigt. Ich verwende die LCD Routinen von 
dieser Seite zur Ansteuerung des LCDs.

Der ganze Code befindet sich hier:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include "lcd-routines.h"
4
#include <avr/interrupt.h>
5
#include <stdlib.h>
6
7
/*
8
Makro for debouncing
9
*/
10
#define debounce( port, pin )                                         \
11
({                                                                    \
12
  static uint8_t flag = 0;     /* new variable on every macro usage */  \
13
  uint8_t i = 0;                                                      \
14
                                                                      \
15
  if( flag ){                  /* check for key release: */           \
16
    for(;;){                   /* loop ... */                         \
17
      if( !(port & 1<<pin) ){  /* ... until key pressed or ... */     \
18
        i = 0;                 /* 0 = bounce */                       \
19
        break;                                                        \
20
      }                                                               \
21
      _delay_us( 98 );         /* * 256 = 25ms */                     \
22
      if( --i == 0 ){          /* ... until key >25ms released */     \
23
        flag = 0;              /* clear press flag */                 \
24
        i = 0;                 /* 0 = key release debounced */        \
25
        break;                                                        \
26
      }                                                               \
27
    }                                                                 \
28
  }else{                       /* else check for key press: */        \
29
    for(;;){                   /* loop ... */                         \
30
      if( (port & 1<<pin) ){   /* ... until key released or ... */    \
31
        i = 0;                 /* 0 = bounce */                       \
32
        break;                                                        \
33
      }                                                               \
34
      _delay_us( 98 );         /* * 256 = 25ms */                     \
35
      if( --i == 0 ){          /* ... until key >25ms pressed */      \
36
        flag = 1;              /* set press flag */                   \
37
        i = 1;                 /* 1 = key press debounced */          \
38
        break;                                                        \
39
      }                                                               \
40
    }                                                                 \
41
  }                                                                   \
42
  i;                           /* return value of Macro */            \
43
})
44
45
46
int main(void)
47
{
48
  DDRD &= ~(1<<PD5);      // Input
49
  PORTD |= (1<<PD5);      // Internal Pull up activated
50
  DDRB |= (1<<PB1);
51
  TCCR1B |= (1<<CS10) | (1<<CS11) | (1<<CS12);
52
  lcd_init();
53
  char buffer[20];
54
55
  while(1)
56
  {
57
    if(debounce(PIND, PD5))
58
    {
59
      itoa(TCNT1,buffer,10);
60
      lcd_clear();
61
      lcd_string(buffer);
62
    }
63
    if(debounce(PIND, PD7))
64
    {
65
      // Unused in this example!
66
    }
67
  }
68
}

Grundsätzlich scheint es auch zu funktionieren. Allerdings wird ab und 
an eine Zahl übersprungen. Soll heißen, das Display gibt z.B. aus:
0,1,3,4,5,7

Weiß jemand, woran es liegt? Ich vermute ggf. ein Problem bei der 
Debounce Routine, bin mir aber nicht sicher.

Ich verwende AVR Studio 4 mit AVRisp mkII und Atmega8 uC.

Dankeschön.

Gruß

von Peter D. (peda)


Lesenswert?

al3ko schrieb:
> Ich vermute ggf. ein Problem bei der
> Debounce Routine,

Nö.
Du benutzt Debounce nur zum Anzeigen, aber zum Zählen T1. Ergo kann sie 
das Zählen auch nicht entprellen.

Nimm ne Variable zum Zählen.


Peter

von al3ko (Gast)


Lesenswert?

Peter Dannegger schrieb:
> al3ko schrieb:
>> Ich vermute ggf. ein Problem bei der
>> Debounce Routine,
>
> Nö.
> Du benutzt Debounce nur zum Anzeigen, aber zum Zählen T1. Ergo kann sie
> das Zählen auch nicht entprellen.
>
> Nimm ne Variable zum Zählen.
>
>
> Peter
Hi Peter,
ich habe dir und deiner Routine unrecht getan, entschuldige bitte. Mit 
der Variable läuft es wie geschmiert.

Okay, hier nun wie ich es verstehe:
Zum zählen (hardwareseitig) verwende ich T1 und da das Debouncing 
softwareseitig realisiert ist, werden an T1 auch die Prellungen 
berücksichtigt. Ergo wird das Prellen mitgezählt, allerdings nur die 
Entprellte Zahl auf dem LCD ausgegeben.

Was mich dabei aber wundert, ist, warum immer nur eine Zahl ausgelassen 
wird und nicht ab und an mal zwei oder mehrere Zahlen?

Danke

von Karl H. (kbuchegg)


Lesenswert?

al3ko schrieb:

> Was mich dabei aber wundert, ist, warum immer nur eine Zahl ausgelassen
> wird und nicht ab und an mal zwei oder mehrere Zahlen?

Wenn du die nächsten paar Tage nichts vor hast, dann setz dich ein paar 
Stunden hin und hämmere auf den Taster ein. Ich würde mal schätzen, 
spätestens nächste Woche wirst du an deinem dann abgenutzten Taster von 
0 bis 5 Preller so ziemlich alles sehen.
Und wenn nicht, dann geht die Tortur für den Taster eben weiter :-) Es 
ist nur eine Frage der Zeit und der Anzahl Betätigungen.

von al3ko (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Wenn du die nächsten paar Tage nichts vor hast, dann setz dich ein paar
> Stunden hin und hämmere auf den Taster ein. Ich würde mal schätzen,
> spätestens nächste Woche wirst du an deinem dann abgenutzten Taster von
> 0 bis 5 Preller so ziemlich alles sehen.
> Und wenn nicht, dann geht die Tortur für den Taster eben weiter :-) Es
> ist nur eine Frage der Zeit und der Anzahl Betätigungen.

Super, vielen Dank. Auch wenn das Experiment sehr attraktiv klingt, so 
belasse ich es dabei und komme zu meiner Konklusion:
T1 ist auch nicht in Kombination mit Tastern zu bringen - genau so wenig 
wie Interruptroutinen (Int0 oder Int1 am Atmega8) :D

Schönen Gruß,
al3ko

von Karl H. (kbuchegg)


Lesenswert?

al3ko schrieb:

> und komme zu meiner Konklusion:
> T1 ist auch nicht in Kombination mit Tastern zu bringen - genau so wenig
> wie Interruptroutinen (Int0 oder Int1 am Atmega8) :D

Dreh deine Konklusio um:
nackte Taster für etwas anderes zu verwenden, als sie per Polling 
abzufragen, ist nicht wirklich sinnvoll. Taster erfordern immer 
Mehraufwand, egal wie. Und wenn schon Mehraufwand, dann kann man sie 
auch gleich Pollen ... und sei es in der ISR eines Timers.

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.