参考教程:[3-1] 独立按键控制LED亮灭_哔哩哔哩_bilibili
1、轻触按键:相当于是一种电子开关,按下时开关接通,松开时开关断开,实现原理是通过轻触按键内部的金属弹片受力弹动来实现接通和断开。
2、按键抖动:对于机械开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开,所以在开关闭合及断开的瞬间会伴随一连串的抖动。
3、开发板原理图中的独立按键模块显示,按键的一端接地,另一端与寄存器P3相连,按下按键,P3中相应的位被置为0,松开按键,P3中相应的位被置为1(引脚采取的是弱上拉,换句话说,当按键不导通时,引脚通过电阻与正电压VCC相连,这时引脚为高电平,当按键导通时,受上拉电阻影响,VCC不能与GND“抗衡”,引脚会受GND影响而处于低电平,不过弱上拉模式的缺点就是高电平驱动能力并不是很好,因为弱上拉电阻的存在会让高电平“并不是那么高”),程序可以获取寄存器P3中的状态进行相应的操作。
4、独立按键状态控制LED灯状态:
(1)在main.c文件中输入以下代码,然后点击“编译”。
#include <REGX52.H>
void main()
{
while(1)
{
if(P3_0 == 0) //P3中的0号位被置为0,检测到按键被按下
P2_0 = 1; //单独对P2的0号位进行操作,按下按键时该位对接的LED灯不亮
else
P2_0 = 0; //如果按键未被按下,LED灯常亮
}
}
(2)按照上一例的操作将生成的.hex文件写进开发板,按动K2按键(K2按键对应P3的0号位)即可观察现象。
5、独立按键控制LED灯状态:
(1)在main.c文件中输入以下代码,借助延时函数进行按键消抖,然后点击“编译”。
#include <REGX52.H>
#include <INTRINS.H> //_nop_()需要这个头文件
void Delay(unsigned int xms) //对借助STC-ISP生成的1ms延时函数进行修改
{
while(xms) //让1ms延时函数重复执行xms次
{
unsigned char i, j;
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
xms--; //smx作为计数器
}
}
void main()
{
while(1)
{
if(P3_1 == 0) //如果按下按键
{
Delay(20); //消除按下按键时的抖动
while(P3_1 == 0); //抖动结束后如果仍未松开开关,LED灯保持原状
Delay(20); //松开按键后上面的循环结束,消除松开按键的抖动
P2_0 = ~P2_0; //LED灯状态反转
}
//每按一次按键,LED灯状态反转一次
}
}
(2)按照上一例的操作将生成的.hex文件写进开发板,按动K1按键(K1按键对应P3的1号位)即可观察现象。
6、独立按键控制LED进行二进制计数:
(1)在main.c文件中输入以下代码,借助延时函数进行按键消抖,然后点击“编译”。
#include <REGX52.H>
#include <INTRINS.H> //_nop_()需要这个头文件
void Delay(unsigned int xms) //对借助STC-ISP生成的1ms延时函数进行修改
{
while(xms--) //让1ms延时函数重复执行xms次
{
unsigned char i, j;
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
void main()
{
P2 = 0xFF; //P2初始化为1111 1111(P2默认的初始状态也是如此)
while(1)
{
static unsigned char LEDNum = 0; //char类型占8位,正好对应P2的8位
//注:unsigned char LEDNum = 0;可以写在循环体外
//但是本人的编译器貌似不允许我这么干,所以才使用static关键字在循环体内部定义计数变量
//加了static关键字后该变量只定义一次,不会重复定义以及重复置为0
if(P3_1 == 0) //每按下一次按键,计数值加一
{
Delay(20);
while(P3_1 == 0);
Delay(20);
LEDNum++; //使用LEDNum进行计数
P2 = ~LEDNum; //因为LED是低电平驱动,所以计数结果取反才符合需求
}
}
}
(2)按照上一例的操作将生成的.hex文件写进开发板,按动K1按键(K1按键对应P3的1号位)即可观察现象。
7、独立按键控制LED移位:
(1)在main.c文件中输入以下代码,然后点击“编译”。
#include <REGX52.H>
#include <INTRINS.H> //_nop_()需要这个头文件
void Delay(unsigned int xms)
{
while(xms--)
{
unsigned char i, j;
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
unsigned char LEDNum = 0; //定义全局变量并初始化为0
void main()
{
P2 = 0xFE; //将P2配置为1111 1110,让第一盏LED灯先亮
while(1)
{
if(P3_1 == 0) //每按一次K1按键,当前LED灯熄灭,下一个LED灯被点亮
{
Delay(20);
while(P3_1 == 0);
Delay(20);
LEDNum++;
if(LEDNum>=8) //一轮循环结束,下一个被点亮的LED灯回到第一盏
LEDNum = 0;
P2 = ~(0x01 << LEDNum); //借助左移运算符简化代码(LED是低电平驱动,记得取反)
}
}
}
(2)按照上一例的操作将生成的.hex文件写进开发板,按动K1按键(K1按键对应P3的1号位)即可观察现象。