MCU独立按键单控LED实现

##江科大视频学习,并且对具体的一些小细节进行更详细的分析。

什么是独立按键?

轻触按键:相当于是一种电子开关,按下开头接通,松开时开头断开,实现原理是通过轻触按键内部的金属弹片受力弹动来实现接通和断开。

注意:GND为负极,按下按键时相当于连通负极,传到给寄存器时反馈为0V,低电平。

松开独立按键则为高电平---5V。

K1对应的是P3_1 K2对应的是P3_0 注意一下。

如图所示:

cpp 复制代码
//P3为独立按键处所控制的寄存器

if(P3_1==0) //当k1按键被按下时

if(P3_1==1) // 当k1按键被松开时

以上便是我们这篇文章所要用到的基本原理。

【3-1】 独立按键控制LED亮灭

cpp 复制代码
#include <REGX52.H>

void main()
{
    while(1)
    {
        if(P3_1==0) //判断独立按键是否被按下
        {
            P2_0=0;//打开第一个LED灯 
        }
        else
        {
            P2_0=1; //关上LED灯
        }

}
/* LED是正极接正极 ,负极接负极才可以亮
此时的LED右边已经是正极VCC了,那么左边就得
为低电平0V才可亮.*/

记得将文件转为HEX文件。

【3-2】 独立按键控制LED状态

1.什么是按键的抖动?

对于机械开关,当机械触点断开,闭合时,由于机械触电的弹性作用,一个开关在闭合时不会马上稳定地接通,在断开时,也不会一下子断开,所以在开关闭合及断开的瞬间会伴随一连串的抖动。其实我们有两种解决方案:

  1. 硬件防止抖动(对于我们实现来说,比较困难)
  2. 软件防抖 (比较轻松实现)

回忆一下,我们有个延迟操作,刚好可以用延迟的时间来覆盖这个抖动时间。

如果忘记怎么操作了,可以看这个---点击[1-2] LED灯闪烁.

2.实现独立按键控制LED状态

cpp 复制代码
#include <REGX52.H>

void Delay(unsigned int xms)		//@12.000MHz
{
	unsigned char i, j;
	while(xms)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
		xms--;
	}

}

void main()
{
    while(1)
    {
    //p3_1指的是k1按键
        if(P3_1==0)
        {
            Delay(20);//20ms刚好覆盖抖动
            while(P3_1==0); //检测按键是否被松开
            Delay(20);//松开抖动 覆盖

        //正式操作
        P2_0=~P2_0;//按位取反

//P2_0的L端口默认为高电频,那么就为1,按位取反后便为0
        }
    }


}

本来的D1的状态为熄灭的是高电平为1,则按位取反后变为低电平为0,则D1灯亮起。

【3-3】独立按键控制LED显示二进制

插入一个知识点:

在MCU编制中,我们通常喜欢用unsigned char 变量名 ,来表示寄存器

因为unsigned char 为八位,符合寄存器大小,其大小范围为0~255。

cpp 复制代码
#include <REGX52.H>
void Delay(unsigned int xms)		//@12.000MHz
{
	unsigned char i, j;
	while(xms--)
	{
			i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}

void main()
{
    //八位二进制 表示一个寄存器
    unsigned char LEDNum=0;
    while(1)
    {
        if(P3_1==0)
        {
            Delay(20);//软件消抖
            while(P3_1==0);//检测松手
            Delay(20);//消抖
            
            LEDNum++;
            P2=~LEDNum; //按位取反,并赋值给P2
        }
    }



}

为何要这么写?因为,常识是对于单片机上的所有L端口,初始都默认为高电平,所以都为寄存器里都为1.那么对于P2寄存器也是如此。

如果我们直接对P2进行--->P2++; 则得到0000 0000;对吧

那么然后,我们在按位取反会发生什么;---> 1111 1111;P2寄存器又回到初始状态了,然后一直这么循环下去,直接卡死在这里。所以,我们就用unsigned char LEDNum来代替寄存器,然它进行++,然后按位取反赋值给P2,便可以实现二进制位移了。

【3-4】独立按键控制LED移位.

cpp 复制代码
#include <REGX52.H>
void Delay(unsigned int xms)		//@12.000MHz
{
	unsigned char i, j;
	while(xms--)
	{
			i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}

//定义一个全局变量
unsigned char LEDNum; //一个寄存器定义

void main()
{
    P2=~0x01;//初始化,让第一个灯亮起来
    if(P3_1==0)
    {
    Delay(20);
    while(P3_1==0);
    Delay(20);
//完成抖动防控后
    
    LEDNum++;
    if(LEDNum>=8)
    {
        LEDNum=0;//回到首位置
    }
    P2=~(0x01<<LEDNum);
    }
//LED灯右移成功

//使用k2按键控制左移

     if(P3_0==0)
    {
    Delay(20);
    while(P3_0==0);
    Delay(20);
//完成抖动防控后 防止越界
    if(LEDNum==0)
    {
        LEDNum=7;//回到最右边
    }
    else
    {
        LEDNum--;
    }
    //进行位移操作
    P2=~(0x01<<LEDNum);
    }

}

对于 << 这个位计算符号,大家可能有所陌生,请看下图。

请亲自动手来实现以上操作,进行加深印象。

今天的内容便是这么多。感谢您的观看

相关推荐
芯橦35 分钟前
【瑞昱RTL8763E】音频
单片机·嵌入式硬件·mcu·物联网·音视频·visual studio code·智能手表
夜间去看海5 小时前
基于单片机的智能浇花系统
单片机·嵌入式硬件·智能浇花
VirtuousLiu5 小时前
LM74912-Q1用作电源开关
单片机·嵌入式硬件·ti·电源设计·lm74912·电源开关
打地基的小白5 小时前
软件I2C-基于江科大源码进行的原理解析和改造升级
stm32·单片机·嵌入式硬件·通信模式·i2c
Echo_cy_6 小时前
STM32 DMA+AD多通道
stm32·单片机·嵌入式硬件
朴人6 小时前
【从零开始实现stm32无刷电机FOC】【实践】【7.2/7 完整代码编写】
stm32·单片机·嵌入式硬件·foc
追梦少年时6 小时前
STM32中断——外部中断
stm32·单片机·嵌入式硬件
bai_lan_ya6 小时前
stm32定时器中断和外部中断
stm32·单片机·嵌入式硬件
玄奕子6 小时前
GPT对话知识库——在STM32的平台下,通过SPI读取和写入Flash的步骤。
stm32·单片机·gpt·嵌入式·嵌入式驱动
夜间去看海7 小时前
基于单片机的温度和烟雾检测
单片机·嵌入式硬件·温度烟雾