独闷闷网
标题: 学习笔记之按键扫描_学“手把手教你单片机架构” [打印本页]
作者: mctrix 时间: 2015-1-30 17:06
标题: 学习笔记之按键扫描_学“手把手教你单片机架构”
—————***********************************—————
志
看到群里高手如云,内心嫉妒且感慨光阴如驹,希望自己能静下心,慢慢的累积,不做知识的”收藏夹“。把感悟体会写出来不奢求能解惑于他人。
—————***********************************—————
最近,把鸿哥的按键扫描部分看完,并且每节都亲自动手再写一遍,感觉收获很大。回想整下,脑海里留下了”框架“和”按键“两个词。
首先,”框架“--三区一线
鸿哥一开始便提出”三区一线“的框架结构,把单片机代码分成可视的几个部分:
拿开会(中国会议多)打个比方:我要主持个会议,那我需要提前到会议现场整理下会议资料(第一区);然后等待所有与会人员到场(分割线);与会人员都到了,交代下会议注意事项不 能抽烟,都关掉手机(第二区);最后开始具体的开会内容(第三区)。
- //三区一线结构
- void main() //主函数
- {
- initial_myself(); //第一区:初始化单片机
复制代码 有什么用?别人的代码就完全没有三区一线吗?有,如果你听过别人介绍自己的代码的话,我想一定听过,"main()开头几行,我是初始化下*****”;
如果你把鸿哥的代码去掉initial_myself();去掉delay_long(100);去掉initial_peripheral();- //没有三区一线 的LED灯闪烁
- void main()
- {
- led_dr = 1; //LED灭
-
- while (1) //循环代码
- {
- ed_dr = 0;
- delay_long(30);
- led_dr = 1;
- delay_long(30);
- }
- }
复制代码 对比上面代码,使用三区一线和不要三区一线,有什么差别!功能上面没有差别,都能实现LED灯的闪烁;但是给人的印象完全不同,使用三区一线,整体的打眼一看,你就知道代码的”思路“, 要实现的功能。
--------------------…………………框架的总结……………………… --------------------
不管是”三区一线“还是initial_myself(); delay_long(100); initial_peripheral(); 转换到现实生活,其实就是-------->命名,俗称”起个名字“;
那为什么要命名呢?打个比方,你公司来个上司,坐在你旁边,就是没有名字,每天你都要找他回报工作,询问计划,沟通交流;你不会发现少点什么吗?在外边偶遇,他没有看到你,你看到了 他,然后你”喂“?”嗨“?”那个“? 所以总结:框架是概括,对概括的整理命名,命名是为了方便(记忆、理解;加深理解)。
作者: mctrix 时间: 2015-1-30 17:15
不能修改吗?。。。
编辑比较乱!!!“三区一线”代码不知道怎么不全- void main()
- {
- initial_myself(); //第一区:初始化单片机
- delay_long(100); //分割线:等待外围上电稳定
- initial_peripheral(); //第二区:初始化外围
- while (1) //第三区:循环扫描非中断应用函数
- {
- device_function();
- }
- }
复制代码
作者: jianhong_wu 时间: 2015-1-30 20:56
很好的分享。果断加精。
作者: mctrix 时间: 2015-1-31 08:49
第二:是“按键”。其实就是对按键扫描功能的代码实现。
在鸿哥的描述中按键分为独立按键和矩阵按键(其实都一回事);按键有上升沿触发;有单击触发,双击触发,按键长短按触发,按键按住加速匀速触发等。
独立按键:
A.独立按键之按键单击触发
这里个人感觉最重要的就是一个按键单击触发:为什么?因为简单,所以好理解,其他按键触发都是在此基础上的修改:
按键单击触发可以分解为两个重点:按键上升沿获取;按键防抖动;
1.按键上升沿获取:其实是单片机对需求的c语言翻译。“按钮按下,蜂鸣器嘀一声”---->蜂鸣器什么时候响,按钮按下的时候。是按下一直响吗?是按钮一直按,松开的时候响吗?都不是,是按钮刚按下,蜂鸣器就动作。其实我们在听到这句话的时候,如果没听过单片机的话,肯定不会想那么多,什么上升沿,下降沿,”按下,蜂鸣器响不就成了“。但是对于单片机来说,你就是要分解的这么细,按钮按下到松开,对它来说有很多步骤。问题来了,如何获取按键上升沿呢?我们回想下,什么是上升沿,就是信号有无到有这个状态;那我们抓这个状态不就成立,当然前提是你给单片机的能区分这个“有”和“无”,先附上代码:
- //1.按下、松开对应信号有无
- if (key_sr == 1) //按钮松开,对应信号无
- {
- ucKeyStatus = 0;
- }
- else
复制代码 未完待续。
作者: mctrix 时间: 2015-1-31 08:50
为什么代码老是,粘不全
- //1.按下、松开对应信号有无
- if (key_sr == 1) //按钮松开,对应信号无
- {
- ucKeyStatus = 0;
- }
- else
- {
- ucKeyStatus = 1 //按钮按下,对应信号有
- }
- //2.以上我们只是抓了个有、无状态,现在我们抓上升沿状态
- if (key_sr ==1)
- {
- ucKeyStatus = 0;
- }
- else if (ucKeyStatus == 0) //按钮按下的瞬间信号无-->其实就是这个状态,要上升沿就是要从0再到1
- {
- ucKeyStatus = 1;
- ucKeySec = 1; //触发了上升沿状态
- }
- //3.那么下降沿呢?同样
- if (key_sr == 0)
- {
- ucKeyStatus = 1; //按钮按下,对应信号有
- }
- else if (ucKeyStatus ==1) //按钮松开瞬间,信号由有到无--就是下降沿
- {
- uckeyStatus =0;
- ucKeyStec = 2; //按键触发下降沿
- }
- //4.按键按下时,按键松开时,其实最简单,第一个代码就是
- if (key_sr == 1) //按键松开
- {
- ucKeyStatus = 0;
- ucKeySec = 3; //按键松开一直触发
- }
- else
- {
- ucKeyStatus = 1;
- ucKeySec = 4; //按键按下,一直触发
- }
复制代码
作者: mctrix 时间: 2015-2-3 10:50
2.按键去抖动:
按键按下的波形情况如图:
可以看出,在按下和松开的时候,波形不是理想的立即切换,而是存在频繁的切换(抖动),然后再稳定的。如果只是使用上升沿来扫描按键按下瞬间的话,如上图在按下过程中会有很多的上升沿,这就可能导致按键按下的误触发,触发多次。这显然不是我们想要的结果--按键太灵敏导致。那如何让按键变得迟钝一点------>那我们就把波动部分滤除掉------>出现波动的话,就取消触发,稳定的我们才触发按键。从波形图中,我们分析,如果按键按下的状态能持续一段时间的话,我们就可以借此来说明按键是按下的。
- //按键去抖动
- if (key_sr == 1)
- {
- ucKeyLock = 0;
- uiKeyTimeCnt = 0; //引入按键按下累计时间计数器,计时清零,为按键按下计时做准备
- }
- else if (ucKeyLock == 0)
- {
- uiKeyTimeCnt++;
- if (uiKeyTimeCnt > CONST_KEY_SENSITIVE) //按键按下状态持续设定时间的话,我们就任务按键按下了,若达不到设定时间,我们就认为是抖动,不处理
- {
- uiKeyTimeCnt = 0; //计时清零,为下次计时准备
- ucKeySec = 1;
- }
- }
复制代码
作者: 重庆-风雪 时间: 2015-2-5 19:57
说的好!
欢迎光临 独闷闷网 (http://dumenmen.com/) |
Powered by Discuz! X3.2 |