哈喽哈喽,我是阿飞的小蝴蝶,大家可以叫我阿飞或者小飞,我又回来啦
经过前两天的更新,相信认真看过的同学们对蓝桥杯板子上LED灯、数码管、蜂鸣器、继电器的使用应该已经没什么大问题了吧,好的,我们今天来讲解一下板子上的下一个模块:机械按键
机械按键呢分位两种使用模式:独立按键和矩阵按键,这两个模式呢是通过板子上的一个硬件部分来切换的,使用方法不相同,但原理都差不多,在大家使用小红板学习的时候这方面都应该也有接触过,没错,它与小红板上的使用方式几乎是相同的,相信很多人在学习都时候都觉得按键很简单对吧,但是大家要注意的是,想要写出一个完全没bug(按键能够特别灵敏地判断状态)的按键其实并不简单,而且它总是结合数码管、LED灯等各种模块来配合使用的,按键各种按下状态中实现各种功能,各种逻辑写起来也是有一定难度的,好的话不多说了,接下来我会用这一节的时间来为大家分别讲解一下独立键盘和矩阵键盘基础知识
我们先来看一下按键部分的原理图:
我们看右边蓝色框框起来引脚可以看到大部分的按键都是通过P3端口来控制的(为什么说是大部分呢,因为板子上的两个引脚有变化:P3^6 --> P4^2; P3^7 --> P4^4),前边说的键盘两种模式是通过左边橙色框里框起来的硬件(对应板子上的J5)来控制的,当跳线帽接2-3时,模式为独立按键;接1-2时,模式为矩阵按键(千万别抬杠哦),好的,我们现在先开始独立按键的讲解:
这里的独立按键与我们小红板上的使用方法是完全一样的,我们看左边红色框里框起来的部分,这四个按键就是独立按键,我们可以看到它右边分别接了P3^0~P3^3引脚,左边通过跳线帽接到了GND,然后我们又知道51单片机在默认状态下,引脚都为高电平,当对应按键按下时,右边的引脚就与左边的GND接在了一起,电平就会被拉低,所以我们直接来判断对应的引脚是否为低电平就可以知道这个按键有没有被按下。
使用按键的时候要注意一点就是机械按键的抖动,我们看下边这张图:
上边蓝色框框起来的是我们理想中的波形图(默认高电平,按下低电平),但实际中的波形是下边红色框框起来的,我们可以看到绿色框中的电平一直在抖动,这段电平就会对我们判断按键是否触发产生干扰,由于板子上没有消除抖动的硬件设计,我们就需要通过程序延时来跳过这段抖动,很简单,只需要在判断引脚电平为低以后加10ms左右的延时,如果这时候引脚电平还是低电平,就代表我们的按键确实被按下了,还有在我们按下没松手的时候,程序会一直循环执行我们这段程序,为了避免这种问题,还需要在按键程序中加入“松手检测”,看下边一段程序:
if(P30 == 0) //判断按键S7是否按下
{
Delay_key(10); //10ms延时用来消抖
if(P30 == 0) //再次判断按键S7是否按下
{
/* 按下S7时需要执行的程序放这里 */
while(P30 == 0); //松手检测
}
}
这就是独立按键的检测函数,嘻,很简单吧?
好的独立按键讲完了我们来讲解一下矩阵按键,(切换的时候记得要把跳线帽换一下哦)这时候我们再看原理图,每行的四个按键都接在了一起,右端分别接在了P3^0、P3^1、P3^2、P3^3引脚,每列的四个按键也接在了一起,左端分别接在了P3^4、P3^5、P4^2、P4^4引脚,当按下一个按键的时候,我们只要想办法判断它是哪一行哪一列的就行啦,通过程序先把P3^4、P3^5、P4^2、P4^4全部拉低,再判断P3^0、P3^1、P3^2、P3^3中哪一个引脚变为了低电平就可以判断第几行按键按下了,同样的方法来判断按键是哪一列的就可以啦,再看下边一段程序:
void key_scan()
{
P34 = P35 = P42 = P44 = 0;
P30 = P31 = P32 = P33 = 1;
if(P30 == 0)
{
delayms(10);
if(P30 == 0) KeyValue = 7;
}
if(P31 == 0)
{
delayms(10);
if(P31 == 0) KeyValue = 6;
}
if(P32 == 0)
{
delayms(10);
if(P32 == 0) KeyValue = 5;
}
if(P33 == 0)
{
delayms(10);
if(P33 == 0) KeyValue = 4;
}
P34 = P35 = P42 = P44 = 1;
P30 = P31 = P32 = P33 = 0;
if(P34 == 0)
{
delayms(10);
if(P34 == 0) KeyValue = KeyValue+12;
while(P34 == 0);
}
if(P35 == 0)
{
delayms(10);
if(P35 == 0) KeyValue = KeyValue+8;
while(P35 == 0);
}
if(P42 == 0)
{
delayms(10);
if(P42 == 0) KeyValue = KeyValue+4;
while(P342 == 0);
}
if(P44 == 0)
{
delayms(10);
if(P44 == 0) KeyValue = KeyValue;
while(P44 == 0);
}
}
这段代码没加注释,是因为我希望大家可以不只依赖于注释,细品一下这段代码,在品的时候多加思考,绝对比只看注释理解得更加透彻
KeyValue是我们在程序最开始定义的一个全局变量,它主要起标志的作用,这就是传说中的标志位,通过判断给它的赋值就可以判断按下的哪一个按键(KeyValue=6 --> 按键6。。。),把这个函数在主函数while循环中执行就可扫描矩阵按键,当然,这只是其中一种判断形式,常用的还有逐行判断等等,大家可以自己试一下。
值得注意的是,我们这里的头文件使用的是“stc15f2k60s2.h”,相较于“reg52.h”,它的功能更加强大,而且在“reg52.h”中是没有P4端口的定义的,在使用的时候要在程序开头部分添加一句代码 “sfr P4 = 0xC0;” 来给P4定义地址,“stc15f2k60s2.h”就不需要了,而且可以直接用 “P30”等 来表示 “P3^0” 等。。
这个头文件的具体添加方法我就不做介绍了,大家可以去看一下祝老师的这篇帖子:http://forum.eepw.com.cn/thread/303029/1
好啦,今天的内容也讲完啦,在走之前呢给大家留下几个小练习,大家可以用自己手头上的小红板或者蓝桥杯什么的练习一下:
1.独立按键与数码管配合使用,数码管显示秒表显示格式为“00-00-00”(分-秒-十毫秒位),按键S4控制秒表开始计时、S5暂停、S6重置(想要把这个完美的写好相对来说还是有些难度的,这里我提示一下大家,使用一个或几个变量来隔10ms+1,数码管是动态数码管,需要在循环中不停的扫描,当按键按下的时候可以使用死循环来停止计数,这时候需要注意:循环中不能什么事情都不做,需要在循环中扫描数码管,否则数码管将不能正常显示,当然如果大家可以使用定时器或外部中断的话,请忽略我这段文字)
2.使用矩阵按键,当按下不同按键的时候数码管任意一位显示按下的键值(S4~S19 分别用 0~f 表示)
好的终于到结尾了,今天的内容就先到这里啦,如果觉得写得还行,可以留言评论一下嘛?(在线卑微~),又不好的地方也欢迎大家指出来,各位加油!预祝大家都能取得好成绩哦!!