原创
一"雨"浇醒梦中人(含“零耗时消除键盘抖动”的C++键盘类源码)
原帖讨论: http://www.21icbbs.com/club/bbs/ShowAnnounce.asp?v=&ID=1715218
一"雨"浇醒梦中人 |
hotpower 发表于 2005-6-28 14:22 AVR 单片机 ←返回版面 |
非常感谢John_Lee!!!!!!!!!!
特别特别感谢testcode!!!!!!!!!
一个"&"号断送了老农的"前程"...这个"雨"---"&"太妙了!!!
在MCU中应用C++确实有些"难为情",但它的风格实在令人难以忘怀...
我明白testcode肯定能够解决这个问题,虽然眼花但很"真情"..."相信您没错"...
两次的救助不知该如何答谢???
特别感谢上次的将整个类不初始化!!! #define __noinit__ __attribute__ ((section (".noinit"))) //变量不初始化
__noinit__ RtcObj Rtc; __noinit__ LedObj Led; __noinit__ KeyObj Key; __noinit__ CtrlObj Ctrl;
只能以此程序向帮助我的网友们报答我的一片真心...
class KeyObj;//键盘模块
class KeyObj { private: unsigned char KeyVal;//每20ms测试的键值(有1无0/有低无高) unsigned char KeyCount;//键盘计数器 unsigned int KeyTest[8];//2.5mS压键计数器 public: KeyObj(void); void KeyInit(void); unsigned char GetKeyVal(void);// void KeyCommandExec(unsigned char); void Exec(void); void Key00(void); void Key01(void); void Key02(void); void Key03(void); void Key04(void);
void Key10(void); void Key11(void); void Key12(void); void Key13(void); void Key14(void);
void Key20(void); void Key21(void); void Key22(void); void Key23(void); void Key24(void); };//键盘模块
__noinit__ KeyObj Key;
//取串行键盘键值 inline unsigned char KeyObj::GetKeyVal(void) { unsigned char KeyVal = 0; PORTC &= ~(1 << KeyCP);//脉冲锁存74HC165并行数据开始 _NOP();//延时 PORTC |= (1 << KeyCP);//脉冲锁存74HC165并行数据结束 for(int i = 8; i > 0; i --) { KeyVal <<= 1; PORTC &= ~(1 << KeyCLK);//发送读键脉冲 _NOP();//延时 if (!(PINC & (1 << KeyData))) KeyVal ++;//数据'1',有键压下为‘1’ PORTC |= (1 << KeyCLK);//发送读键脉冲 } return KeyVal;//无键压下为0 }
//键扫描及运行(每2.5mS运行一次,实现“零耗时消除键盘抖动”) inline void KeyObj::Exec(void)//此程序套在定时中断中 { static const unsigned char KeyTab[8] PROGMEM = {//只取当前键值表 0b10000000,//键盘0 0b01000000,//键盘1 0b00100000,//键盘2 0b00010000,//键盘3 0b00001000,//键盘4 0b00000100,//短接线0 0b00000010,//短接线1 0b00000001 //短接线2 }; KeyCount &= 0x07;//只有8个键 KeyVal = GetKeyVal();//取所有键位值 if (KeyVal & pgm_read_byte(&KeyTab[KeyCount])) {//有键压下(每次只取1键以实现“零耗时消除键盘抖动”) if (KeyTest[KeyCount] < 1200) {//1200*2.5mS=3S//压键长短判别 KeyTest[KeyCount] ++;//计数每20mS键盘压键的次数(选2较好些) if (KeyTest[KeyCount] == 2) {//键刚压下//短压键 KeyCommandExec(1);//短压键事件处理(1) } } else {//长压键 2.5mS*1200=3S KeyTest[KeyCount] = 2;//再压3S继续执行下一次长压键 KeyCommandExec(2);//长压键3S事件处理(2) } } else {//无键压下 if (KeyTest[KeyCount] >= 2) {//键释放 KeyCommandExec(0);//键释放事件处理(0) } else {//无键压下或干扰 } KeyTest[KeyCount] = 0;//清除压键计数器 } KeyCount ++;//为下次扫描做准备 KeyCount &= 0x07;//只有8个键 }
typedef prog_void (KeyObj::* PFV)(void); void KeyObj::KeyCommandExec(unsigned char mode) { static const PFV KeyCommandTab[3][5] = {//键盘事件处理表 {&KeyObj::Key00, &KeyObj::Key01, &KeyObj::Key02, &KeyObj::Key03, &KeyObj::Key04}, //键释放事件处理 {&KeyObj::Key10, &KeyObj::Key11, &KeyObj::Key12, &KeyObj::Key13, &KeyObj::Key14}, //压键事件处理 {&KeyObj::Key20, &KeyObj::Key21, &KeyObj::Key22, &KeyObj::Key23, &KeyObj::Key24} //长压键事件处理 }; KeyCount &= 0x07;//取键盘序号 if (KeyCount <= 4) {//只有5个键,KeyCount>=5为3个短接线 (::Key.*KeyCommandTab[(int)mode][(int)KeyCount])();//运行KeyX0()~KeyX4() } }
/*------------------------ 键释放事件处理 ------------------------*/ void KeyObj::Key00(void) { }
void KeyObj::Key01(void) { }
void KeyObj::Key02(void) { }
void KeyObj::Key03(void) { }
void KeyObj::Key04(void) { }
/*------------------------ 压键事件处理 ------------------------*/ void KeyObj::Key10(void) { }
void KeyObj::Key11(void) { }
void KeyObj::Key12(void) { }
void KeyObj::Key13(void) { }
void KeyObj::Key14(void) { }
/*------------------------ 长压键事件处理 ------------------------*/ void KeyObj::Key20(void) { }
void KeyObj::Key21(void) { }
void KeyObj::Key22(void) { }
void KeyObj::Key23(void) { }
void KeyObj::Key24(void) { }
|
|
文章评论(0条评论)
登录后参与讨论