引言
按键是一种常见的电子开关,按下时开关接通,松开时开关断开。其实现原理是通过轻触按键内部的金属弹片受力弹动来实现接通和断开。
实物图
开发板IO连接图
J19与P2相连,JP1与J20相连,可根据自己的开发板来进行选择,代码也要做适当修改
按键原理图
工作原理
从上图可以看到,当单片机上电时,与JP1相连的寄存器的IO口默认是高电平。当按键按下时,IO口接GND(地)。当寄存器写入一个值,它就会输送到IO口中,同时寄存器会检测这个IO口的电平,并读取到寄存器中,此时我们可以通过代码进行检测是否被按下。
按键抖动
在按键检测中需要加入延时,其主要目的是为了消除按键抖动。按键抖动是指在按键按下或松开的瞬间,电路中会产生一系列快速的高低电平变化。这种抖动会导致单片机误判按键的状态,从而引发错误的操作。通过在检测到按键按下后加入一个短暂的延时,可以让按键抖动的影响消失,再次检测按键状态时,如果仍然是按下状态,才认为按键确实被按下了。这种方法可以有效地提高按键检测的可靠性。
代码演示1
#include <REGX52.H>
void DelayXms(unsigned int xms) //@12.000MHz
{
unsigned char data i, j;
while(xms)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void Init_Port()
{
P2 = 0xff;
}
void main()
{
Init_Port();//端口初始化
while(1)
{
if(P1_0 == 0)
{
DelayXms(1);//消除抖动
if(P1_0 == 0)
{
P2_0 = 0; //点亮LED1
}
}else{
P2_0 = 1;
}
}
}
首先调用Init_Port函数进行端口初始化。然后进入一个无限循环,检测P1.0引脚的状态:如果P1.0引脚为低电平(按键按下),则调用DelayXms(1)函数进行1毫秒的延时,以消除按键抖动。再次检测P1.0引脚的状态,如果仍为低电平,则将P2.0引脚设置为低电平(点亮LED1)。如果P1.0引脚为高电平(按键松开),则将P2.0引脚设置为高电平(熄灭LED1)。这段代码实现了一个简单的按键控制LED灯的功能。当按下按键连接到P1.0时,LED1(连接到P2.0)将被点亮;当松开按键时,LED1将熄灭。
- DelayXms函数用于产生延时。参数xms表示延时的毫秒数。内部通过两个嵌套的循环来实现延时,具体延时长度取决于系统时钟频率(这里为12MHz)。
- Init_Port函数用于初始化端口。这里将P2端口的所有引脚设置为高电平(0xFF)。
代码演示2
#include <REGX52.H>
void DelayXms(unsigned int xms) //@12.000MHz
{
unsigned char data i, j;
while(xms)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void Init_Port()
{
P2 = 0xff;
}
void main()
{
Init_Port();//端口初始化
while(1)
{
if(P1_0 == 0)
{
DelayXms(5);
while(P1_0 == 0);
DelayXms(5);
P2_0 = ~P2_0; //切换LED1的状态
}
}
}
首先调用Init_Port函数进行端口初始化。然后进入一个无限循环,检测P1.0引脚的状态:如果P1.0引脚为低电平(按键按下),则调用DelayXms(5)函数进行5毫秒的延时。持续检测P1.0引脚的状态,直到按键松开(P1.0引脚变为高电平)。
再次调用DelayXms(5)函数进行5毫秒的延时。切换P2.0引脚的状态(即如果P2.0原来是高电平,则变为低电平,反之亦然),从而实现LED1的状态切换。这段代码实现了一个按键控制LED灯状态切换的功能。每次按下并松开按键,LED1的状态都会改变一次。
代码演示3
#include <REGX52.H>
void DelayXms(unsigned int xms) //@12.000MHz
{
unsigned char data i, j;
while(xms)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void Init_Port()
{
P2 = 0xff;
}
void main()
{
Init_Port();
while(1)
{
if(P1_0 == 0)
{
DelayXms(5);
while(P1_0 == 0);
DelayXms(5);
if(P2 > 0)
{
P2--;
}else
{
Init_Port();
}
}
}
}
运行之后,将 P2 端口的所有位设置为高电平(0xFF),即初始化状态。之后进入无限循环,检测 P1_0 按键状态:如果按键按下(P1_0 == 0),延时 5 毫秒进行消抖。再次检测按键状态,确保按键仍然按下。如果 P2 的值大于 0,递减 P2 的值;否则,调用 Init_Port 重置 P2 端口。从LED1到LED8,8位二进制的方式进行LED灯的控制。