|
发表于 2010-11-12 22:29:08
|
显示全部楼层
you have a good concept but the code isn't modular enough.
here is what I would recommend:
==========code=============
#include <regx51.h>
#include "gpio.h"
//hardware configuration
#define KEY_PORT P2
#define KEY_PORT_IN P2
#define KEY_DDR P2
#define KEY0 (1<<3) //key0 on key_port.3
#define KEY1 (1<<3) //key1 on key_port.3
#define KEY2 (1<<3) //key2 on key_port.3
#define KEY_LOOP 50 //number of loops for debouncing
#define LED_PORT KEY_PORT
#define LED_DDR KEY_DDR
#define LED0 (1<<0) //ledo on key_port.0
#define LED1 (1<<1) //led1 on key_port.1
#define LED2 (LED0 | LED1) //led2 = led0+led1
//end hardware configuration
unsigned char key_read(unsigned char keys) {
unsigned char tmp; //temp variable
static unsigned char keys_prev=0; //read out from the last call
tmp=keys_prev; //save keys_prev
keys_prev=IO_GET(KEY_PORT_IN, keys); //read the button, active high
return (tmp ^ keys_prev); //1) returns bits that have changed
//return (tmp ^ keys_prev) & tmp; //2) return s bits that have changed from high to low / falling edge
//return (tmp ^ keys_prev) & keys_prev; //3) returns bits that have changed from low to high / rising edge
}
unsigned char key_read_sm(unsigned char keys) {
unsigned char tmp;
unsigned short loop=KEY_LOOP;
tmp=key_read(keys); //read the keys
if (tmp) //key has been pressed
while (loop--) if (key_read(keys)) return 0x00;
return tmp; //loop exhausted -> keys did stablize
}
void mcu_init(void) {
IO_IN(KEY_DDR, KEY0 | KEY1 | KEY2); //key0/key1/key2 as input
IO_CLR(LED_PORT, LED2); //led2 cleared
IO_OUT(LED_DDR, LED2); //led2 as output
}
int main(void) {
mcu_init(); //reset the mcu
while (1) {
if (key_read_sm(KEY0)) IO_FLP(LED_PORT, LED0); //if key0 is pressed, flip led0
else IO_FLP(LED_PORT, LED1); //flip led1
}
}
=============end code=============
it utilizes two routines: key_read() that returns 1 if a key has seen its level changed (by using the different return statements in key_read(), you can read level changes, or falling edges or rising edges), and key_read_sm() that returns a valid key read only if the key remains stabilized over a given number of cycles (defined by KEY_LOOP).
no global variables, all you need is those two routines.
see the simulation below:
(原文件名:26. key debouncing.gif)
KEY0 simulates a bouncing key press, as in the time period highlighted by red traces, between 0.5ms and 1.3ms. it stabilizes after that.
LED0 is the debounced output: it stays low while KEY0 is being stabilized and then stay stabilized during the next KEY_LOOP (=50) consecutive reads before it is considered a valid read.
the code is entirely C so it is portable to any mcu that has a c compiler.
you can customize the code to your application by tailoring the hardware configuration section, at the beginning at the code.
hope it helps. |
|