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