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

}

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

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

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

相关推荐
scan112 小时前
单片机串口接收状态机STM32
stm32·单片机·串口·51·串口接收
Qingniu0113 小时前
【青牛科技】应用方案 | RTC实时时钟芯片D8563和D1302
科技·单片机·嵌入式硬件·实时音视频·安防·工控·储能
深圳市青牛科技实业有限公司14 小时前
【青牛科技】应用方案|D2587A高压大电流DC-DC
人工智能·科技·单片机·嵌入式硬件·机器人·安防监控
Mr.谢尔比15 小时前
电赛入门之软件stm32keil+cubemx
stm32·单片机·嵌入式硬件·mcu·信息与通信·信号处理
LightningJie15 小时前
STM32中ARR(自动重装寄存器)为什么要减1
stm32·单片机·嵌入式硬件
西瓜籽@16 小时前
STM32——毕设基于单片机的多功能节能窗控制系统
stm32·单片机·课程设计
远翔调光芯片^1382879887218 小时前
远翔升压恒流芯片FP7209X与FP7209M什么区别?做以下应用市场摄影补光灯、便携灯、智能家居(调光)市场、太阳能、车灯、洗墙灯、舞台灯必看!
科技·单片机·智能家居·能源
极客小张19 小时前
基于STM32的智能充电桩:集成RTOS、MQTT与SQLite的先进管理系统设计思路
stm32·单片机·嵌入式硬件·mqtt·sqlite·毕业设计·智能充电桩
m0_739312871 天前
【STM32】项目实战——OV7725/OV2604摄像头颜色识别检测(开源)
stm32·单片机·嵌入式硬件
嵌入式小章1 天前
基于STM32的实时时钟(RTC)教学
stm32·嵌入式硬件·实时音视频