完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
堵塞式按键消抖
如下是一个最基本的堵塞式按键程序: ***it K1 = P1^0; ***it K1 = P1^1; ***it K1 = P1^2; ***it K1 = P1^3; #define KEY_VALUE_NULL 0X00 #define KEY_VALUE_1 0X01 #define KEY_VALUE_1 0X02 #define KEY_VALUE_1 0X04 #define KEY_VALUE_1 0X08 void delay_ms(unsigned char xms) { unsigned char i,j; for(i = xms;i > 0;i--){ for(j = 110;j > 0;j--); } } unsigned char KeyScan(void) { unsigned char temp = KEY_VALUE_NULL; if(K1 == 0){ delay_ms(20); if(K1 == 0){ temp = KEY_VALUE_1; } } if(K2 == 0){ delay_ms(20); if(K1 == 0){ temp = KEY_VALUE_2; } } if(K3 == 0){ delay_ms(20); if(K1 == 0){ temp = KEY_VALUE_3; } } if(K4 == 0){ delay_ms(20); if(K1 == 0){ temp = KEY_VALUE_4; } } return temp; } void main(void) { unsigned char keyValue = 0; while(1) { keyValue = KeyScan(); if(keyValue == KEY_VALUE_1){ //按键1按下执行代码段 } if(keyValue == KEY_VALUE_2){ //按键2按下执行代码段 } if(keyValue == KEY_VALUE_3){ //按键3按下执行代码段 } if(keyValue == KEY_VALUE_4){ //按键4按下执行代码段 } } } 该代码具有堵塞式按键的通病,那就是当按键按下后,所有的CPU时间都用来空跑,对于实时性高的任务,这20ms消抖会带来很多灾难性后果。20ms够我们跑很大量级的指令数了。我们怎么不使用delay来完成按键消抖呢? 时基法编程之按键消抖 如下是一个最基本的非堵塞式按键程序: ***it K1 = P1^0; ***it K1 = P1^1; ***it K1 = P1^2; ***it K1 = P1^3; #define KEY_VALUE_NULL 0X00 #define KEY_VALUE_1 0X01 #define KEY_VALUE_1 0X02 #define KEY_VALUE_1 0X04 #define KEY_VALUE_1 0X08 unsigned char keyValue = 0;//按键键值接口 unsigned char keyScan1ms = 0;//按键时基驱动接口 //读取按键IO口电平 unsigned char KeyScan(void) { unsigned char temp = KEY_VALUE_NULL; if(K1 == 0){ temp = KEY_VALUE_1; } if(K2 == 0){ temp = KEY_VALUE_2; } if(K3 == 0){ temp = KEY_VALUE_3; } if(K4 == 0){ temp = KEY_VALUE_4; } return temp; } void keyProcess(void) { static unsigned char keyLastValue = KEY_VALUE_NULL;//上次键值 static unsigned char keyNowValue = KEY_VALUE_NULL;//当前键值 static unsigned char keyFilterCnt = 0;//消抖计数器 //时基法编程核心语句 if(keyScan1ms < 10)return;//按键扫描时基未到10ms,则退出 keyScan1ms = 0;//千万不能忘记清零时基 keyNowValue = KeyScan();//读取此时IO口电平 if(keyNowValue != KEY_VALUE_NULL){//按键被按下 if(keyNowValue != keyLastValue){//此次按键跟上次按键键值不一样 keyFilterCnt = 0; } keyFilterCnt++;//消抖核心语句 } else{//按键松开 //10ms采样一次,松手之前连续3次以上采样到按键按下。 if(keyFilterCnt > 3){ keyValue = keyLastValue; } keyFilterCnt = 0;//清消抖计数器 } keyLastValue = keyNowValue; } void main(void) { //定时器初始化.... while(1) { keyProcess(); if(keyValue == KEY_VALUE_1){ keyValue = 0;//使用后手动清键值 //按键1被按下执行代码 } //...... //其它进程... } } //定时器中断1ms void Timer0_Interrupt() interrupt 1 { keyScan1ms ++; } 上面代码是一个最基本的非堵塞式按键,仅仅实现按键消抖,但其有非常好的扩展性,诸如组合按键、长按、单双击都可以按照这种方式实现。在此不做细述,留待读者深入体会。 非堵塞式编程的优点是非常显然的,比如将前面文章的流水灯+蜂鸣器鸣叫+LED闪烁等等进程添加进来,程序不会有任何卡顿现象出现。但如果用堵塞式编程,则程序会出现明显的卡顿现象。 但是堵塞式也并不是无可取之处,因其逻辑简单、稳定,它在处理实时性要求不高的场合非常适用。 |
|
|
|
只有小组成员才能发言,加入小组>>
imx6ull 和 lan8742 工作起来不正常, ping 老是丢包
2461 浏览 0 评论
3341 浏览 9 评论
3022 浏览 16 评论
3514 浏览 1 评论
9118 浏览 16 评论
1243浏览 3评论
636浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
627浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2373浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1936浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-24 06:24 , Processed in 1.237081 second(s), Total 76, Slave 57 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号