tclm2m救砖3n手机中间按键长按不灵了,短按可以,有人知道怎么调试吗?

春花秋月何时了?活动不能少。无奈上海路又遥,21ic探报……
MWC(世界移动通信大会)22号正式开幕了,手机不再唱主角,……
无论是 《机械公敌》 里的终极大BOSS还是POI的the machi……
ApplePay自从今年3月正式入华,不少人在尝鲜之后都大呼……
演讲人:黄孝旋时间: 10:00:00
演讲人:陶瑜浦时间: 10:00:00
演讲人:张亚晖时间: 10:00:00
预算:¥5,000-¥10000预算:¥5,000-¥10000
第11节:同一个按键短按与长按的区别触发
[导读]从业将近十年!手把手教你单片机程序框架 第十一节:开场白:上一节讲了类似电脑键盘组合按键触发的功能,这节要教会大家一个知识点:如何在上一节的基础上,略作修改,就可以实现同一个按键短按与长按的区别触发。具
从业将近十年!手把手教你单片机程序框架 第十一节:
上一节讲了类似电脑键盘组合按键触发的功能,这节要教会大家一个知识点:如何在上一节的基础上,略作修改,就可以实现同一个按键短按与长按的区别触发。
具体内容,请看源代码讲解。
(1)硬件平台:基于朱兆祺51单片机学习板。用矩阵键盘中的S1和S5号键作为独立按键,记得把输出线P0.4一直输出低电平,模拟独立按键的触发地GND。
(2)实现功能:两个独立按键S1和S5,按住其中一个按键,在短时间内松手,则认为是短按,触发蜂鸣器短鸣一声。如果一直按住这个按键不松手,那么超过规定的长时间内,则认为是长按,触发蜂鸣器长鸣一声。
(3)源代码讲解如下:
#include &REG52.H&
#define const_voice_short 20 //蜂鸣器短叫的持续时间
#define const_voice_long 140 //蜂鸣器长叫的持续时间
/* 注释一:
* 调整抖动时间阀值的大小,可以更改按键的触发灵敏度。
* 去抖动的时间本质上等于累计定时中断次数的时间。
#define const_key_time_short1 20 //短按的按键去抖动延时的时间
#define const_key_time_long1 400 //长按的按键去抖动延时的时间
#define const_key_time_short2 20 //短按的按键去抖动延时的时间
#define const_key_time_long2 400 //长按的按键去抖动延时的时间
void initial_myself();&
void initial_peripheral();
void delay_long(unsigned int uiDelaylong);
void T0_time(); //定时中断函数
void key_service(); //按键服务的应用程序
void key_scan(); //按键扫描函数 放在定时中断里
sbit key_sr1=P0^0; //对应朱兆祺学习板的S1键
sbit key_sr2=P0^1; //对应朱兆祺学习板的S5键
sbit key_gnd_dr=P0^4; //模拟独立按键的地GND,因此必须一直输出低电平
sbit beep_dr=P2^7; //蜂鸣器的驱动IO口
unsigned char ucKeySec=0; //被触发的按键编号
unsigned int uiKeyTimeCnt1=0; //按键去抖动延时计数器
unsigned char ucKeyLock1=0; //按键触发后自锁的变量标志
unsigned char ucShortTouchFlag1=0; //短按的触发标志
unsigned int uiKeyTimeCnt2=0; //按键去抖动延时计数器
unsigned char ucKeyLock2=0; //按键触发后自锁的变量标志
unsigned char ucShortTouchFlag2=0; //短按的触发标志
unsigned int uiVoiceCnt=0; //蜂鸣器鸣叫的持续时间计数器
void main()&
initial_myself();&
delay_long(100);&
initial_peripheral();&
key_service(); //按键服务的应用程序
void key_scan()//按键扫描函数 放在定时中断里
/* 注释二:
* 长按与短按的按键扫描的详细过程:
* 第一步:平时只要按键没有被按下时,按键的自锁标志,去抖动延时计数器一直被清零。
* 第二步:一旦两个按键都被按下,去抖动延时计数器开始在定时中断函数里累加,在还没累加到
* 阀值const_key_time_short1或者const_key_time_long1时,如果在这期间由于受外界干扰或者按键抖动,而使
* IO口突然瞬间触发成高电平,这个时候马上把延时计数器uiKeyTimeCnt1
* 清零了,这个过程非常巧妙,非常有效地去除瞬间的杂波干扰。这是我实战中摸索出来的。
* 以后凡是用到开关感应器的时候,都可以用类似这样的方法去干扰。
* 第三步:如果按键按下的时间超过了短按阀值const_key_time_short1,则马上把短按标志ucShortTouchFlag1=1;
* 如果还没有松手,一旦发现按下的时间超过长按阀值const_key_time_long1时,
* 先把短按标志ucShortTouchFlag1清零,然后触发长按。在这段程序里,把自锁标志ucKeyLock1置位,
* 是为了防止按住按键不松手后一直触发。
* 第四步:等按键松开后,自锁标志ucKeyLock12及时清零,为下一次自锁做准备。如果发现ucShortTouchFlag1等于1,
* 说明短按有效,这时触发一次短按。
* 第五步:以上整个过程,就是识别按键IO口下降沿触发的过程。
if(key_sr1==1)//IO是高电平,说明两个按键没有全部被按下,这时要及时清零一些标志位
ucKeyLock1=0; //按键自锁标志清零
uiKeyTimeCnt1=0;//按键去抖动延时计数器清零,此行非常巧妙,是我实战中摸索出来的。&
if(ucShortTouchFlag1==1) //短按触发标志
ucShortTouchFlag1=0;
ucKeySec=1; //触发一号键的短按
else if(ucKeyLock1==0)//有按键按下,且是第一次被按下
uiKeyTimeCnt1++; //累加定时中断次数
if(uiKeyTimeCnt1&const_key_time_short1)&
ucShortTouchFlag1=1; //激活按键短按的有效标志&
if(uiKeyTimeCnt1&const_key_time_long1)&
ucShortTouchFlag1=0; //清除按键短按的有效标志
uiKeyTimeCnt1=0;&
ucKeyLock1=1; //自锁按键置位,避免一直触发
ucKeySec=2; //触发1号键的长按
if(key_sr2==1)//IO是高电平,说明两个按键没有全部被按下,这时要及时清零一些标志位
ucKeyLock2=0; //按键自锁标志清零
uiKeyTimeCnt2=0;//按键去抖动延时计数器清零,此行非常巧妙,是我实战中摸索出来的。&
if(ucShortTouchFlag2==1) //短按触发标志
ucShortTouchFlag2=0;
ucKeySec=3; //触发2号键的短按
else if(ucKeyLock2==0)//有按键按下,且是第一次被按下
uiKeyTimeCnt2++; //累加定时中断次数
if(uiKeyTimeCnt2&const_key_time_short2)&
ucShortTouchFlag2=1; //激活按键短按的有效标志&
if(uiKeyTimeCnt2&const_key_time_long2)&
ucShortTouchFlag2=0; //清除按键短按的有效标志
uiKeyTimeCnt2=0;&
ucKeyLock2=1; //自锁按键置位,避免一直触发
ucKeySec=4; //触发2号键的长按
void key_service() //第三区 按键服务的应用程序
switch(ucKeySec) //按键服务状态切换
case 1:// 1号键的短按 对应朱兆祺学习板的S1键
uiVoiceCnt=const_voice_ //按键声音的短触发,滴一声就停。
ucKeySec=0; //响应按键服务处理程序后,按键编号清零,避免一致触发
case 2:// 1号键的长按 对应朱兆祺学习板的S1键
uiVoiceCnt=const_voice_ //按键声音的长触发,滴一声就停。
ucKeySec=0; //响应按键服务处理程序后,按键编号清零,避免一致触发
case 3:// 2号键的短按 对应朱兆祺学习板的S5键
uiVoiceCnt=const_voice_ //按键声音的短触发,滴一声就停。
ucKeySec=0; //响应按键服务处理程序后,按键编号清零,避免一致触发
case 4:// 2号键的长按 对应朱兆祺学习板的S5键
uiVoiceCnt=const_voice_ //按键声音的长触发,滴一声就停。
ucKeySec=0; //响应按键服务处理程序后,按键编号清零,避免一致触发
void T0_time() interrupt 1
TF0=0; //清除中断标志
TR0=0; //关中断
key_scan(); //按键扫描函数
if(uiVoiceCnt!=0)
uiVoiceCnt--; //每次进入定时中断都自减1,直到等于零为止。才停止鸣叫
beep_dr=0; //蜂鸣器是PNP三极管控制,低电平就开始鸣叫。
; //此处多加一个空指令,想维持跟if括号语句的数量对称,都是两条指令。不加也可以。
beep_dr=1; //蜂鸣器是PNP三极管控制,高电平就停止鸣叫。
TH0=0xf8; //重装初始值()=f
TR0=1; //开中断
void delay_long(unsigned int uiDelayLong)
for(i=0;i&uiDelayLi++)
for(j=0;j&500;j++) //内嵌循环的空指令数量
; //一个分号相当于执行一条空语句
void initial_myself() //第一区 初始化单片机
/* 注释三:
* 矩阵键盘也可以做独立按键,前提是把某一根公共输出线输出低电平,
* 模拟独立按键的触发地,本程序中,把key_gnd_dr输出低电平。
* 朱兆祺51学习板的S1和S5两个按键就是本程序中用到的两个独立按键。
key_gnd_dr=0; //模拟独立按键的地GND,因此必须一直输出低电平
beep_dr=1; //用PNP三极管控制蜂鸣器,输出高电平时不叫。
TMOD=0x01; //设置定时器0为工作方式1
TH0=0xf8; //重装初始值()=f
void initial_peripheral() //第二区 初始化外围
EA=1; //开总中断
ET0=1; //允许定时中断
TR0=1; //启动定时中断
总结陈词:
在很多需要人机交互的项目中,需要用按键来快速加减某个数值,这个时候如果按住一个按键不松手,这个数值要有节奏地快速往上加或者快速往下减。要现实这种功能,我们该怎么写程序?欲知详情,请听下回分解-----按住一个独立按键不松手的连续步进触发。
  通用运动控制技术现状、发展及其应用:运动控制技术的发展是制造自动化前进的旋律,是推动新的产业革命的关键技术。运动控制器已经从以单片机或微处理器作为核心的运动控制器和以专用芯片(ASIC)作为核心处理器的......关键字:
英特尔于日宣布了4004处理器及其芯片集,它是芯片巨人第一个完整的单片机和第一个商业微处理器。4004处理器有2300个晶体管,手指甲大小,计算性能与第一代电子计算机相当,但第一代计算机需要占据整间房......关键字:
爱可视的平板产品覆盖面很广,既有面向儿童推出的 7 寸 Arnova Child Pad,又有配置键盘的 101 XS,现在他们又推出了为游戏玩家准备的 GamePad。这款 7 寸平板采用了双核 1.5GHz 处理器、4 核 Mali ......关键字:
说说我对于物联网的看法。首先,可以肯定的是,物联网肯定是将来发展的一个大方向,这个毋庸置疑,但是物联网的真正崛起可能还需要一段时间。要让物能联网,必须要有一个微型的控制器,这个控制器就是所谓的单片机,这个单片机的功能不需要很强,但是最好能低......关键字:
作为一名热衷于AM硬件开发平台的工程师,树莓派(Raspberry Pi)引发了不少爱好者的狂热。但是奔往梦想的路途永无止境,如果你想要更多一些的能量,尤其是x86的加持,那当前正在Kickstarter上众筹的JaguarBoard显然是......关键字:
作为过来人思前想后,我感到完全有责任将发自心底的感受传递给年轻一代,“一个企业家心灵深处渴望优秀人才的卓越追求和深层次的叹息、痛苦和感受”。您们千万不要等到毕业求职时才觉得自己能力太差,世界上从来就没有后悔药。......关键字:
我 要 评 论
热门关键词查看: 4437|回复: 9
问一下原子兄,哪个例程有按键短按和长按实现不同功能的?谢谢
主题帖子精华
高级会员, 积分 999, 距离下一级还需 1 积分
在线时间9 小时
如题,烦请告知,谢谢啦。
主题帖子精华
金牌会员, 积分 1553, 距离下一级还需 1447 积分
在线时间2 小时
这很容易实现吧.
学习交流请加Q群:(STM32F4交流群)
主题帖子精华
高级会员, 积分 999, 距离下一级还需 1 积分
在线时间9 小时
是容易实现,不过想用更可靠,稳定的方法。
主题帖子精华
高级会员, 积分 506, 距离下一级还需 494 积分
在线时间0 小时
我来给楼主传一个,不是一般的好用,用在项目上没问题的。
&实现按键的检测,具有软件滤波机制
(1) 按键按下
(2) 按键弹起
(3) 长按键
(4) 长按时自动连发
(5) 组合键
21:05 上传
点击文件名下载附件
475.7 KB, 下载次数: 2843
主题帖子精华
在线时间361 小时
回复【楼主位】螃蟹爱虫:
---------------------------------
给按键返回值带一个参数:时间参数。
这样你自己检测这个参数即可。
我是开源电子网站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺:
微信公众平台:正点原子
主题帖子精华
初级会员, 积分 124, 距离下一级还需 76 积分
在线时间0 小时
回复【4楼】Eric2013:
---------------------------------
看了一下还不错
主题帖子精华
高级会员, 积分 999, 距离下一级还需 1 积分
在线时间9 小时
搞好了,就是感觉有点复杂了。
主题帖子精华
中级会员, 积分 286, 距离下一级还需 214 积分
在线时间12 小时
回复【7楼】螃蟹爱虫:
---------------------------------
能发图按键长按部分做参考下吗?
主题帖子精华
高级会员, 积分 601, 距离下一级还需 399 积分
在线时间92 小时
学习了!设计的很巧妙!
主题帖子精华
初级会员, 积分 77, 距离下一级还需 123 积分
在线时间7 小时
学习了,很不错
Powered by后使用快捷导航没有帐号?
查看: 8606|回复: 10
分析一个按键程序(长按 短按 双击)
在线时间40 小时
威望142 分
TA的帖子TA的资源
一粒金砂(中级), 积分 142, 距离下一级还需 58 积分
一粒金砂(中级), 积分 142, 距离下一级还需 58 积分
如果我们要分析什么,我们就要身临其境地把自己想成是什么。
对于按键:我们需要思考的问题有:
1&&按键本身有哪几个状态?
&&&闲置&按下&弹起&state_kidel&state_kdown&state_kup
按键在任何情况下,都只有这3中状态,值得注意的是闲置和弹起本质上是有很大的区别的。
2&&&人对于按键有什么划分?人是怎么看按键的呢?
&&&不按&短按&双击&长按
那么,我们程序中要处理的就是&短按&双击&和&长按。
LONG_KEY&&&TWICE_KEY&&&LONG_KEY_UP&
而区分这些状态,需要一个用于参考的时间:
&KEY_LONGTIME&&KEY_TWICETIME
当我们的头脑中有了这样的分析以后呢?就要开始准备程序了。
按键:每隔一定时间,扫描一次。扫描标志(gbKeyScanInt_Flag)
(1)判断是键盘还是触摸
如果是键盘,按键按下是的电平是1变成0。Keyport是key_data取反(在汇编中,是求补并加1)
按键的进程:闲置&—&&按下&—&&弹起
本帖子中包含更多资源
才可以下载或查看,没有帐号?
在线时间40 小时
威望142 分
TA的帖子TA的资源
一粒金砂(中级), 积分 142, 距离下一级还需 58 积分
一粒金砂(中级), 积分 142, 距离下一级还需 58 积分
STATE_KIDEL:
如果有按键,查表,看是第几个按键。(排除8个IO口中,你不用做按键的那些IO。另外也是keyport中是从0开始的,而记在temp中是从0开始的)。
& &&&Key_ThisValue=temp+1;& && & 当前键值
& &&&KeyState=STATTE_KDOWN;& &按键状态
& &&&KeyDn_Cnt=KEY_LONGTIME; 按键按下持续时间置为KEY_LONGTIME,减到0就表示长按时间到了。
如果没有按键,break跳出。
STATE_KDOWN:
如果按键松开了,判断长按时间到。
& &&&--& 如果长按时间到了,
& &&&Key_OldValue=0;
& &&&KeyState=STATE_KIDEL;回到闲置状态
& &&&gKeyBuf=Key_ThisValue+LONG_KEY_UP;
& &&&gbHaveKey=TRUE;
& &&&——————& 长按
& &&&--& 如果长按时间还没有到,如果按键抬起了,有可能是双击。
& &&&KeyState=STATE_KUP;设置了KeyState为STATE_UP,如果时间到了,表示按键按下后,又弹起,弹起的时间够了。
& &&&KeyUp)Cnt=KEY_TWICETIME;
& &&&如果按键没有松开
& &&&--& 如果长按时间到了
& &&&Key_ThisValue+=LONG_KEY;
& &&&gKeyBuf=Key_ThisV
& && &gbHaveKey=TRUE;
& && &———————&长按
& && &--&如果长按时间没有到,按键还按着的话,就自减1.
& && & KeyDn_Cnt--;
STATE_KUP:
如果按键抬起时间到了
& &&&--&如果 旧的键值=当前键值
& && & Key_ThisValue+=TWICE_KEY;& &&&当前Key值+Twice_key
& && & Key_OldValue=0;& && && && && &&&j
& && & KeyState=STATE_KIDEL;& &
& && & gKeyBuf=Key_ThisV
& && & gbHaveKey=TRUE;& &
& &&&—————————&双击
& &&&--&如果 旧的键值 !=当前键值
& && & KeyState=STATE_KIDEL;
&&& & & && & gKeyBuf = Key_ThisV
& & & && & gbHaveKey = TRUE;& & & & & & & & // ------有键值& & & &
& &&&——————————&有短按
如果按键抬起时间没有到
& && & KeyUp_Cnt--;
& && &--&如果KeyPort!=0
& && & KeyState=STATE_KIDEL;
& && & Key_OldValue=Key_ThisV
& & & & ———————————&有新按键&&
& & & & 接下来,我们来具体分析几个可能出现的例子。
& & & & 1& 按键由闲置进入按下,
& & & & --&STATE_KIDEL
& & & & --&STATE_KDOWN
& & & & 刚按下时,键盘没有松开,长按等待时间也还没有到,就KeyDn_Cnt--;
& & & & (1)如果KeyDn_Cnt减到了0,此时按键还没有松开,就是长按了,进行处理后,向上提交长按键值。
& & & & (2)过了很久,键盘松开了。仍然在STATE_KDOWN中
进入 按键已松开,长按时间到,有些东西归位,进行处理后,向上提交长按抬起键值。
& & & & (3)如果长按等待时间还没有到,按键松开了
更改按键状态 --&STATE_KUP,并使用KeyUp_Cnt为KEY_TWICETIME。
& &进入按键抬起状态
如果按键刚刚弹起了,双击等待时间还没有到,就KeyUp_Cnt--;
& & & & 如果这时,又有按键按下,扫描到KeyPort!=0
则又进入--&STATE_KIDEL,然后Key_OldValue=Key_ThisValue,
又重新开始,如果是按下同样的键,如果这个同样的键按下的时间达到了长按时间,则丢弃之前的Key_OldValue,向上提交长按按键或长按抬起按键。
如果这个同样的键按下的时间不够长按时间,就抬起了。则进入STATE_KUP,如果在
KEY_TWICETIME之内,没有新的按键,则双击等待时间为0以后,判断Key_OldValue==Key_ThisValue,一定是等于的,则进行处理后,向上提交双击键值。
& && &(2)如果这时,双击等待时间到了,keyPort=0,中间没有按键。
& && && &则比较Key_OldValue=0,不等于Key_ThisValue。有些东西归位,处理后向上提交短按键值
还有一点啊:如果你;连续的按按键,那么本程序处理的只是最后两个按键,或一个按键。
在线时间55 小时
威望248 分
芯币305 枚
TA的帖子TA的资源
一粒金砂(高级), 积分 248, 距离下一级还需 252 积分
一粒金砂(高级), 积分 248, 距离下一级还需 252 积分
泪奔一次。。。。支持一下。
在线时间25 小时
威望138 分
TA的帖子TA的资源
一粒金砂(中级), 积分 138, 距离下一级还需 62 积分
一粒金砂(中级), 积分 138, 距离下一级还需 62 积分
不错的分析
在线时间1052 小时
威望3219 分
芯币2886 枚
E金币85 枚
TA的帖子TA的资源
五彩晶圆(初级), 积分 3219, 距离下一级还需 281 积分
五彩晶圆(初级), 积分 3219, 距离下一级还需 281 积分
这个真的很不错
在线时间1673 小时
威望2462 分
芯币11441 枚
E金币158 枚
TA的帖子TA的资源
支持一下,确实不错,讲解的比较清楚,也比较使用!:carnation:
在线时间1 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
不错的程序,有收获
在线时间16 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
在线时间2 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
很好的资料,谢谢
在线时间4 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
分析的很好,受到启发
在线时间33 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 2, 距离下一级还需 3 积分
一粒金砂(初级), 积分 2, 距离下一级还需 3 积分
不错的程序,有收获
Powered by
逛了这许久,何不进去瞧瞧?关于按键长按和短按的问题??_单片机吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:118,426贴子:
关于按键长按和短按的问题??收藏
想实现短按按键KEY灯LED0变换状态,长按按键KEY(&2S)灯LED1变换状态。但是我写完发现如果实现长按则短按的LED0也会变换状态,不知道怎么更改,还望朋友们指教。程序贴图在楼下。
实邦电子多年专注于单片机产品开发,为客户提供电子产品解决方案,已成功开发100多款产品.我们拥有多位经验的电子工程师,为您的产品提供优异的设计,稳定可靠的电路设计.
用定时器定时准确得多,更好用
流程 while(1)左大括号if (!key)左大括号延时 10msif (time&200)左大括号if (!key) 左大括号time+=20右大括号else左大括号time=0短按右大括号右大括号else左大括号time=0长按右大括号右大括号手机打的,自己修改,右大括号——来自it知识库
短按那里你可以自己加个时间判断2s内就可以了!——来自it知识库
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或红米按键长按怎么变短按_百度知道

我要回帖

更多关于 tcl m2m 的文章

 

随机推荐