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ß