#define N_key 0 //无键 #define S_key 1 //单键 #define C_key 2 //连键 #define L_key 3 //长键 #define key_state_0 0 #define key_state_1 1 #define key_state_2 2 #define key_state_3 3 //******************短按,长按功能函数***************// Uint16 read_key() { static Uint16 key_state = 0,key_time=0; //key1_state 要定义为全局变量 Uint16 key_press,key_return=N_key; key_press = GpioDataRegs.GPBDAT.bit.GPIO54; // 读按键 I/O 电平 switch (key_state) { case key_state_0: // 按键初始态 if (!key_press) key_state = key_state_1; // 键被按下,状态转换到键确认态 break; case key_state_1: // 按键确认态 if (!key_press) { key_time = 0; // key_return = 1; // 按键仍按下,按键确认输出为“1” key_state = key_state_2; // 状态转换到键释放态 } else key_state = key_state_0; // 按键已抬起,转换到按键初始态 break; case key_state_2: if (key_press) { key_return = S_key; // 此时按键释放,说明是产生一次短操作,回送S_key key_state = key_state_0; // 转换到按键初始态 } else if (++key_time >= 100) // 继续按下,计时加10ms(10ms为本函数循环执行间隔) { key_return = L_key; // 按下时间>1000ms,此按键为长按操作,返回长键事件 key_state = key_state_3; // 转换到等待按键释放状态 } break; //key_state = key_state_0; //按键已释放,转换到按键初始态 //break; case key_state_3: // 等待按键释放状态,此状态只返回无按键事件 if (key_press) key_state = key_state_0; //按键已释放,转换到按键初始态 break; } return (key_return); } //******************连续按键功能函数***************// Uint16 key_read() { static Uint16 key_m = key_state_0, key_time_1 = 0; Uint16 key_return = N_key,key_temp; key_temp = read_key(); switch(key_m) { case key_state_0: if (key_temp == S_key ) { key_time_1 = 0; // 第1次单击,不返回,到下个状态判断后面是否出现双击 key_m = key_state_1; } else key_return = key_temp; // 对于无键、长键,返回原事件 break; case key_state_1: if (GpioDataRegs.GPBDAT.bit.GPIO54==1) { key_m = key_state_0; // 按键已释放,转换到按键初始态 key_return = 1; // 输出“1” } else if (++key_time_1 >= 100) // 按键时间计数 { key_m = key_state_2; // 按下时间>1s,状态转换到计时 2 key_time_1 = 0; // 清按键计数器 key_return = 2; // 输出“2” } break; case key_state_2: if (GpioDataRegs.GPBDAT.bit.GPIO54==1) key_m = key_state_0; //按键已释放,转换到按键初始态 else { if (++key_time_1 >= 50) // 按键时间计数 { key_time_1 = 0; // 按下时间>0.5s,清按键计数器 key_return = 2; // 输出“2” } } break; } return key_return; }
收藏0 举报
Uint16 readC_key() { static Uint16 key_state = 0,key_time=0; //key1_state 要定义为全局变量 Uint16 key_press,key_return=N_key; key_press = GpioDataRegs.GPBDAT.bit.GPIO54; // 读按键 I/O 电平 switch (key_state) { case key_state_0: // 按键初始态 if (!key_press) key_state = key_state_1; // 键被按下,状态转换到键确认态 break; case key_state_1: // 按键确认态 if (!key_press) { key_time = 0; // key_return = 1; // 按键仍按下,按键确认输出为“1” key_state = key_state_2; // 状态转换到键释放态 } else key_state = key_state_0; // 按键已抬起,转换到按键初始态 break; case key_state_2: if (key_press) { key_return = S_key; // 此时按键释放,说明是产生一次短操作,回送S_key key_state = key_state_0; // 转换到按键初始态 } else if (++key_time >= 100) // 继续按下,计时加10ms(10ms为本函数循环执行间隔) { key_return = L_key; // 按下时间>1000ms,此按键为长按操作,返回长键事件 key_state = key_state_3; // 转换到等待按键释放状态 } break; //key_state = key_state_0; //按键已释放,转换到按键初始态 //break; case key_state_3: // 等待按键释放状态,此状态只返回无按键事件 if (key_press) key_state = key_state_0; //按键已释放,转换到按键初始态 else if (++key_time >= 50) // 按键时间计数 { key_state = key_state_4; // 按下时间>1s,状态转换到计时 2 key_time = 0; // 清按键计数器 key_return = C_key; // 输出“2” } break; case key_state_4: if (key_press) key_state = key_state_0; //按键已释放,转换到按键初始态 else { if (++key_time >= 50) // 按键时间计数 { key_time = 0; // 按下时间>0.5s,清按键计数器 key_return = C_key; // 输出“2” } } break; } return (key_return); }
595332542 发表于 2013-8-27 22:21 额。。。没人看么 现在通过这样的状态转换可以实现上述功能,无按键——有按键——有短按——有长按——有 ...
zhangmangui 发表于 2013-8-28 10:01 个人觉得按键会有抖动 所以单击和连击这两个就不好处理 不知道你的按键之后有没有硬件整形电路没 没的 ...
595332542 发表于 2013-8-28 14:59 我用定时器每10ms进行检测的方法去抖动的,抖动可以消除,就是现在连发不知怎么实现。 ...
gygp 发表于 2013-8-29 10:03 或者使用定时器扫描的方法。
595332542 发表于 2013-8-29 11:37 我使用的是定时器扫描的方法,通过设置一个计数单位可以实现长按,短按功能,但连续触发功能(就是按下去 ...
本版积分规则 发表回复 回帖并转播 回帖后跳转到最后一页
人才类勋章
时间类勋章
发帖类勋章
等级类勋章
30
77
3
扫码关注 21ic 官方微信
扫码关注嵌入式微处理器
扫码关注电源系统设计
扫码关注21ic项目外包
扫码浏览21ic手机版
本站介绍 | 申请友情链接 | 欢迎投稿 | 隐私声明 | 广告业务 | 网站地图 | 联系我们 | 诚聘英才
京公网安备 11010802024343号