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);
    }

}

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

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

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

相关推荐
梦境虽美,却不长1 小时前
51单片机快速入门之 SPI通信 2025年4月29日09:26:32
单片机·嵌入式硬件·51单片机·spi通信
XWXnb62 小时前
STM32 中断系统深度剖析
c语言·开发语言·stm32·嵌入式硬件
光子物联单片机2 小时前
GD32F407单片机开发入门(十七)内部RTC实时时钟及实战含源码
stm32·单片机·嵌入式硬件·mcu·gd32单片机
.似水2 小时前
2025.4.26_STM32_SPI
stm32·单片机·嵌入式硬件
小智学长 | 嵌入式4 小时前
单片机-89C51部分:8、定时器
单片机·嵌入式硬件
nuannuan2311a10 小时前
97AB-ASEMI机器人功率器件专用97AB
单片机
bloxd yzh11 小时前
简易版2D我的世界C++程序(有点BUG,但是可以玩!!!)
stm32·单片机·嵌入式硬件
落雨封海12 小时前
【5】GD32 基础通信外设:USART、I2C、SPI
单片机
yt9483214 小时前
STM32裸机编程架构与思路
单片机·嵌入式硬件
夜月yeyue18 小时前
STM32 USB配置详解
stm32·单片机·嵌入式硬件