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

}

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

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

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

相关推荐
一路往蓝-Anbo1 小时前
【第13期】中断机制详解 :从向量表到ISR
c语言·开发语言·stm32·单片机·嵌入式硬件
ArrebolJiuZhou2 小时前
00 arm开发环境的搭建
linux·arm开发·单片机·嵌入式硬件
易水寒陈2 小时前
使用J-Link RTT Viewer
stm32·单片机
少一倍的优雅3 小时前
hi3863(ws63)智能小车 (三)PWM驱动马达
单片机·嵌入式硬件·hi3863
xingzhemengyou13 小时前
STM32 内存空间中的选项字节
stm32·单片机
v先v关v住v获v取4 小时前
椰子采摘机械臂设计cad9张+三维图+设计说明书
科技·单片机·51单片机
就是蠢啊5 小时前
51单片机——TFTLCD显示器(一)
嵌入式硬件·计算机外设·51单片机
qq_448011165 小时前
嵌入式中IO、GPIO、专用IO
单片机·嵌入式硬件
xingzhemengyou16 小时前
STM32 Boot0 与 Boot1 [当 Flash 被误操作锁死或 SWD/JTAG 无法连接时,很有用]
stm32·单片机·嵌入式硬件
恒锐丰小吕6 小时前
屹晶微 EG27710 600V耐压、高性能、快速开关的半桥驱动芯片技术解析
嵌入式硬件·性能优化·硬件工程