#ifndef _KEY_H #define _KEY_H #include "Typedef.h" #define K1 0x01 #define K2 0x02 #define K3 0x04 #define K4 0x08 #define K5 0x10 #define K6 0x20 #define K7 0x40 #define K8 0x80 #define K_TIM(T) (T/5) #define K_ONE_TIM (K_TIM(24)) #define K_CON_TIM (K_TIM(700)) #define K_MAX_TIM (K_TIM(10000)) typedef struct { u8 Key; // 按键状态 u16 Tim; // 按键时间 u8 One; // 单次有效按键,只用一次 u8 Up; // 按键放开,只用一次 u8 Con; // 连续有效按键, }KeyType; extern KeyType Key; ////////////////////// void Key_Init(void); u8 GetKeyPin(void); // 按键引脚 void KeyDrv(void); // 驱动 //////////////////////// KeyType GetKey(void); #endif复制#include "io.h" #include "stdlib.h" #include "key.h" static KeyType KeyVol; KeyType Key; ////////////////////////////////////// // Key IO 操作 ////////////////////////////////////// void Key_Init(void) { IO_Key_Init( ); } u8 GetKeyPin(void) //按键引脚 { return IO_GetKeyPin( ); } ///////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////// KeyType GetKey(void) { static KeyType _key; // 禁用中断,也可以用标志位实现 // disable_interrupt( ); _key = KeyVol; KeyVol.One = 0; KeyVol.Up = 0; // enableInterrupts( ); //开中断 return _key; } void KeyDrv(void) //驱动 { static u8 Tmp_u8; Tmp_u8 = GetKeyPin(); //没有按键 调用频率,最高到最低排列,减少CPU占用时间 if(Tmp_u8 == 0) { //按键放开 if(KeyVol.Key != 0) KeyVol.Up = KeyVol.Key; KeyVol.Con = 0; KeyVol.Tim = 0;KeyVol.Key = 0; return; } //按键没变 if(Tmp_u8 == KeyVol.Key) { //最大按键有效时间 if(KeyVol.Tim < K_MAX_TIM) KeyVol.Tim++; //按键连按有效 if(KeyVol.Tim > K_CON_TIM) {KeyVol.Con = Tmp_u8;return;} //按键首次有效 if(KeyVol.Tim == K_ONE_TIM) {KeyVol.One = Tmp_u8;} return; } //按键改变 {KeyVol.Key = Tmp_u8; KeyVol.Tim = 0; return;} }修改以下两个函数,对应硬件 void Key_Init(void) u8 GetKeyPin(void) //按键引脚 void KeyDrv(void) 这个是周期调用的,一般我是和LED动态显示一起处理,调好.H文件的时间定义就好了; KeyType GetKey(void) 用户调用,返回按键值 没有测试的一个例子: main() { int cont; Timer_Inti(); //200HZ Key_Init(); while(1) { Key = GwtKey(); switch(Key.One) 单次有效,如果怕与连续有冲突可以用Key.up,就是按键放开 { case: break;..... } switch(Key.One | Key.Con) 单次和连续有效,表现为按下K1后数值加1,之后大约800MS左右就连续加1,速度是主循环的时间,常用100MS处理一次就是10HZ { case K1: Cont ++; break;..... } if(Key.Tim > TIM(2) && (Key.Con == K2) ){长按2秒处理} print(cont); wait(100); } }
#include "io.h" #include "stdlib.h" #include "key.h" static KeyType KeyVol; KeyType Key; ////////////////////////////////////// // Key IO 操作 ////////////////////////////////////// void Key_Init(void) { IO_Key_Init( ); } u8 GetKeyPin(void) //按键引脚 { return IO_GetKeyPin( ); } ///////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////// KeyType GetKey(void) { static KeyType _key; // 禁用中断,也可以用标志位实现 // disable_interrupt( ); _key = KeyVol; KeyVol.One = 0; KeyVol.Up = 0; // enableInterrupts( ); //开中断 return _key; } void KeyDrv(void) //驱动 { static u8 Tmp_u8; Tmp_u8 = GetKeyPin(); //没有按键 调用频率,最高到最低排列,减少CPU占用时间 if(Tmp_u8 == 0) { //按键放开 if(KeyVol.Key != 0) KeyVol.Up = KeyVol.Key; KeyVol.Con = 0; KeyVol.Tim = 0;KeyVol.Key = 0; return; } //按键没变 if(Tmp_u8 == KeyVol.Key) { //最大按键有效时间 if(KeyVol.Tim < K_MAX_TIM) KeyVol.Tim++; //按键连按有效 if(KeyVol.Tim > K_CON_TIM) {KeyVol.Con = Tmp_u8;return;} //按键首次有效 if(KeyVol.Tim == K_ONE_TIM) {KeyVol.One = Tmp_u8;} return; } //按键改变 {KeyVol.Key = Tmp_u8; KeyVol.Tim = 0; return;} }修改以下两个函数,对应硬件 void Key_Init(void) u8 GetKeyPin(void) //按键引脚 void KeyDrv(void) 这个是周期调用的,一般我是和LED动态显示一起处理,调好.H文件的时间定义就好了; KeyType GetKey(void) 用户调用,返回按键值 没有测试的一个例子: main() { int cont; Timer_Inti(); //200HZ Key_Init(); while(1) { Key = GwtKey(); switch(Key.One) 单次有效,如果怕与连续有冲突可以用Key.up,就是按键放开 { case: break;..... } switch(Key.One | Key.Con) 单次和连续有效,表现为按下K1后数值加1,之后大约800MS左右就连续加1,速度是主循环的时间,常用100MS处理一次就是10HZ { case K1: Cont ++; break;..... } if(Key.Tim > TIM(2) && (Key.Con == K2) ){长按2秒处理} print(cont); wait(100); } }
收藏4 举报
您需要 登录 才可以下载或查看,没有账号?注册
逍遥派掌门 发表于 2016-5-12 16:52 思路不错,但是楼主没有考虑按键的震荡,补上就更好了。
mcu5i51 发表于 2016-5-13 08:30 按键的震荡,不是很明白什么意思,如果是指的去抖动的话,已经有了
逍遥派掌门 发表于 2016-5-17 14:32 去抖动,是在main里面的wait(100) 吗? 如果是的话,这种方式不好。
本版积分规则 发表回复 回帖并转播 回帖后跳转到最后一页
等级类勋章
发帖类勋章
时间类勋章
人才类勋章
5
1889
9
扫码关注 21ic 官方微信
扫码关注嵌入式微处理器
扫码关注电源系统设计
扫码关注21ic项目外包
扫码浏览21ic手机版
本站介绍 | 申请友情链接 | 欢迎投稿 | 隐私声明 | 广告业务 | 网站地图 | 联系我们 | 诚聘英才
京公网安备 11010802024343号