51单片机按键
键盘检测原理及应用实现
作者:超级鹏鹏
一.关于键盘的一些简单介绍
键盘分为编码键盘和非编码键盘。键盘上闭合的键的识别由专门的硬件编码器实现,并产生键编码号或键值的称为编码键盘,如计算机键盘。而靠软件编程来识别的键盘称为非编码键盘,在单片机组成的各种系统中,用的较多的是非编码键盘。非编码键盘又分为独立键盘和行列式键盘。
我们先来看这块板子上的独立按键
:
按键的一端共地,另外一端,三个按键分别连接在CPU的P3.2P3.3P3.4三个端口上。如果按键被按下,那么我们可以检测到这三个端口应该是低电平。
还有一个知识点要在这里说明:就是按键的消抖。
按键在闭合和断开的时候,会有触点存在抖动现象,就如上图那样,所以我们在检测键盘是否按下都要加上去抖动的操作,利用软件延时:就是先判断一下按键是否按下?二.小试牛刀
我们自己编程来尝试一下吧!!!#include#defineucharunsignedchar#defineuint
unsignedint
//定义一个独立键盘
检测按键是否释放
延迟10ms
执行相应代码
sbitkey=P3^2;ucharcodetable[16]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};ucharcodeled_w[8]ucharnum=0;voiddelay(uint);
={0,1,2,3,4,5,6,7};
/**********************************************************名称:main()
功能:通过一个独立按键使得每按一次按键,数码管上的数字加一**********************************************************/voidmain(){
while(1){if(key==0)
{
delay(10);
if(key==0)
的被按下,执行下面内容
{num++;if(num==10)
9时,再从0重新开始
num=0;
}
while(!key);delay(10);
//消抖,先判断一次//延迟一下
//再判断一下,如果真
//数码管上显示到
//判断是否按键弹起来
while(!key);}else
P0=table[num];P2=led_w[0];
//数码管段值//点亮某一位数码管
}}
/**********************************************************名称:delay()功能:延迟函数
**********************************************************/voiddelay(uintx){
uinta,b;for(a=x;a>0;a--)
for(b=110;b>0;b--);
}
按下第一个独立按键,是不是数字开始从0~9呢!!!恭喜你,你成功了!!!
三.矩阵键盘检测
独立键盘与单片机连接时,每一个按键都需要单片机的一个IO口,若某单片机系统需要较多的按键,如果用独立按键便会占用过多的IO口资源。单片机的IO口资源比较宝贵,所以当用到多个按键时,为了节省IO
线,我们引入矩阵键盘。
我们可以看出矩阵键盘没有共地端,所以我们在检测按键有没有被按下时,可以先送一列低电平,其余几列都为高电平,立即轮流检测一次各行是否有低电平,若检测到某一行为低电平,则我们可以确定当前按键被按下的键是哪一行哪一列的。我们可以利用这种方法检测完全部按键。同样我们也可以将行线置低电平检测列线。
Ok,我们有了以前独立按键的基础,又有了上述讲的知识,那么我们还是从编程中取得想要的结果吧!!#include#include#defineucharunsignedchar
#defineuintunsignedint
voiddelay(uint);
ucharcodetable[16]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
/*******************************************************名称:keyscan()
功能:实现按键的读取,并返回相应的按键位置
*******************************************************/ucharkeyscan(){
ucharbuffer[]={0xfe,0xfd,0xfb,0xf7};//每一行线分别为低电平的数组uchari,j,temp;for(i=0;i
P1=buffer[i];
线为低电平
delay(1);
P1口
temp=0x10;
//同时//稳定住//每一行
读取列线,利用一个temp变量
for(j=0;j
//扫描列线
if(!(temp&P1))
temp与P1口相与为0,那么此按键被按下
{
return(i*4+j);}
temp
此列没被按下,temp向左移,扫描其它列
}}}
//如果
//返回按键的值
//如果
/*******************************************************名称:main()
功能:主函数,通过数码管显示是哪一个按键被按下
*******************************************************/voidmain(){
ucharkeynum;while(1)
{
P1=0x0f;
全部列线为低电平
if(P1!=0x0f)
键按下
{
delay(20);if(P1!=0x0f){
keynum=keyscan();
//按键消抖//按键消抖
//令键盘
//按键消抖,是否有按
//执行按键扫描程序
}
P0=table[keynum];P2=0;;}}}
//数码管显示
/*******************************************************名称:delay()功能:延迟函数
*******************************************************/voiddelay(uintx){
uinta,b;for(a=x;a>0;a--)
for(b=110;b>0;b--);
}
四.后记
现在想必你已经对按键的知识有点上手了吧,只要你自己慢慢捉摸,相信你一定会对按键这块知识理解的非常到位!!
超级鹏鹏
于2012.2.9写于姥姥家