问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

51单片机独立按键控制LED的几种应用场景

创作时间:
作者:
@小白创作中心

51单片机独立按键控制LED的几种应用场景

引用
CSDN
1.
https://blog.csdn.net/m0_55642878/article/details/138999027

本文将详细介绍51单片机独立按键控制LED的几种应用场景,包括按键控制LED亮灭、按键控制LED状态切换、按键控制LED显示二进制以及按键控制LED移位等功能。通过具体的代码实现和原理讲解,帮助读者掌握独立按键在单片机中的应用。

一、什么是独立按键?

如图所示,独立按键在开发板的左下角,K1~K4。

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

独立按键在开发板原理图中的样子如下图所示。

二、独立按键控制LED亮灭

目标:按下K1按键时D1灯亮,松开K1按键后D1灯灭。

创建项目,添加main.c,添加头文件

#include <REGX52.H>

main()

之前点亮LED是通过寄存器P2点亮的,这个寄存器是8个为一组的。

#include <REGX52.H>
void main()
{
    P2 = 0xfe;
    while(1)
    {
        
    }
}

如果直接操作P2,点亮D1灯需要同时给8个寄存器赋值。如何只操作P2的最低位而不影响其他位?

代开头文件

可以看到sfr定义了8位一体的寄存器P2

继续往下翻,也可以看到位寄存器

我们可以通过位寄存器单独操作每个寄存器

三、独立按键控制LED状态

目标:按下K1按键后D1灯亮,再按一下后D1灯灭,再按一下又亮。

按键的抖动:对于机械开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开,所以在开关闭合及断开的瞬间会伴随一连串的抖动。

如何避免这种抖动?可以从软件层面解决,错过波动阶段:按下按键之后延时20ms,松开按键之后延时20ms

#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)
    {
        if(P3_1 == 0)
        {
            Delay(20);//按键消抖,按下
            while(P3_1 == 0);//保持住P3_1 == 0
            Delay(20);//按键消抖,松开
            P2_0 = ~P2_0;
        }
    }
}

为什么

P2_0 = ~P2_0;

这行代码要按位取反?

P2_0

默认是高电平,不亮。按下K1后

P3_1 == 0

,松开后

P3_1 == 1

,要想让D1灯亮,就要让

P2_0 == 0

,那么就要给P2_0取反,即

P2_0 = ~P2_0;

。再次按下K1后

P3_1 == 0

,松开后

P3_1 == 1

,要想让D1灯灭,就要让

P2_0 == 1

,那么就要给P2_0取反,即

P2_0 = ~P2_0;

四、独立按键控制LED显示二进制

在Keil5中,新建项目,添加main.c,插入头文件,写main()函数。

在stc-isp的“软件延时计算器”中,生成12MHz、1毫秒、STC-Y1指令集的代码,复制粘贴到Keil5

把Delay1ms()改为Delay(unsigned int xms),内部加入while(xms)循环

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

也可以while(xms)循环体内也可以把xms–删掉,把while(xms)改为while(xms–)

主函数写成

void main()
{
    while(1)
    {
        if(P3_1 == 0)
        {
            Delay(20);
            while(P3_1 == 0);//保持住P3_1 == 0
            Delay(20);
            P2--;
            
        }
    }
}

build一下,把程序下载下来就可以实现LED按二进制点亮。

主函数也可以这么些:

void main()
{
    unsigned int LEDNum=0;
    while(1)
    {
        if(P3_1 == 0)
        {
            Delay(20);
            while(P3_1 == 0);//检测松手
            Delay(20);
            LEDNum++;
            P2 = ~LEDNum;
        }
    }
}

五、独立按键控制LED移位

功能1:按下K1,亮的LED左移。

#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()
{
    unsigned char LEDNum=0;
    while(1)
    {
        if(P3_1 == 0)
        {
            Delay(20);
            while(P3_1 == 0);
            Delay(20);
            
            LEDNum++;
            if(LEDNum>=8)
            {
                LEDNum = 0;
            }
            P2 = ~(0x01<<LEDNum);//向左移位
            
        }
    }
}

下载程序后会发现上电后D1灯没亮,按下K1后D2灯开始亮,直到下一次循环,D1才会亮。这是因为P2默认为 1111 1111,需要先对P2初始化,即在while(1)循环之前令

P2 = ~0x01;

功能2:按下K1,LED左移,按下K2,LED右移。

#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()
{
    unsigned char LEDNum=0;
    P2 = ~0x01;
    while(1)
    {
        if(P3_1 == 0)
        {
            Delay(20);
            while(P3_1 == 0);
            Delay(20);
            
            LEDNum++;
            if(LEDNum>=8)
            {
                LEDNum = 0;
            }
            P2 = ~(0x01<<LEDNum);//向左移位
            
        }
        if(P3_0 == 0)
        {
            Delay(20);
            while(P3_0 == 0);
            Delay(20);
            
            if(LEDNum<=0)
            {
                LEDNum = 7;
            }
            else
                LEDNum--;
            P2 = ~(0x01<<LEDNum);
        }
    }
}
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号