51单片机独立按键控制led灯

51单片机实现通过独立按键切换流水灯和呼吸灯两种模式 且通过独立按键控制流水灯和呼吸灯的速度 普中开发版

刚刚随手撸的代码,供参考(io配置基于MCS51普中A2开发板,软件延时版本)
关键点是两个,一个是按键切换任务,一个是设定一个变量控制时间间隔
有更具体的要求可以私聊


/* Head Line ------------------------------------------------------------------- */
#include<reg52.h> //51单片机的头文件
#include<intrins.h> //程序中需要使用到空指令_nop_ ();字符循环移位指令_crol_等时使用
/* Type Def -------------------------------------------------------------------- */
typedef unsigned char u8;
typedef unsigned int u16;
//typedef 为C语言的关键字,作用是为一种数据类型定义一个新名字,这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等)。
//typedef 本身是一种存储类的关键字,与 auto、extern、static、register 等关键字不能出现在同一个表达式中。
/* IO Define ------------------------------------------------------------------- */
#define LED   P2
sbit HX_LED=P2^0;
sbit KEY1=P3^1;
sbit KEY2=P3^0;
//_sbit  定义特殊功能寄存器的位变量。bit和sbit都是C51扩展的变量类型。
//_sbit 的应用相当于给一个特定的引脚一个名字,其意义在于方便位操作
/* Var ------------------------------------------------------------------------- */
#define TaskNum 2 
#define SpeedLevel 5
u8    SL[5] = {1,2,5,10,20};
u8    Sset = 0;
u8  Snum = 5;
u8  fTask = 0;
/* Functions ------------------------------------------------------------------- */
/* Delays -------------------------------- */
//利用stc-isp软件内置的软件延时代码生成器生成代码
//可以自行加以修改实现更便利的操作
void Delayus(u16 i)        //@12.000MHz
{
    do{
        _nop_();
    } while (--i);
}

void Delayms(u16 i)        
{
    do{
        Delayus(1000);
    } while (--i);
}
/* LED Flow ------------------------------- */
void LED_Flow(void)
{
    while(fTask==0 && KEY1!=0 && KEY2!=0)
    {
        Delayms(SL[Sset]*100);//延时xxms
        LED = _crol_(LED,1);
    }
}
/* LED Brth ------------------------------- */
void LED_Brth(void)
{
    u8 hxflag=1;
    u16 hxjg=150;
    LED=0xfe;
    while(fTask==1 && KEY1!=0 && KEY2!=0)
    {
        if(hxflag==1) hxjg--;
        if(hxflag==0) hxjg++;
        
        HX_LED = !HX_LED;
        Delayus((hxjg)*SL[Sset]);//延时xxms
        HX_LED = !HX_LED;
        Delayus((300-hxjg)*SL[Sset]);//延时xxms
        
        if(hxjg==290||hxjg==10)hxflag=1-hxflag;
    }
}
/* KEY Scan ------------------------------- */
void KEY_Scan(void)
{
    //KEY2
    if(KEY2==0)
    {
        Delayms(1);//消抖
        if(KEY2==0)
        {
            Sset++;
            if(Sset==Snum)Sset=0;
        }while(!KEY2);
    }
    //KEY1
    if(KEY1==0)
    {
        Delayms(1);//消抖,时间1-20ms均可
        if(KEY1==0)//程序块内写按下按键后执行的内容
        {
            fTask++;
            if(fTask==TaskNum)fTask=0;
        }while(!KEY1);//阻塞,按键松开后程序继续运行
    }
}
/* Main ------------------------------------------------------------------------ */
void main(void)
{
    LED =0xfe;
    
    while(1)
    {
        KEY_Scan();//调用 按键扫描 函数
            
        switch(fTask)
        {
            case 0: LED_Flow(); break;//自定义工作状态0 流水灯
            case 1: LED_Brth(); break;//自定义工作状态1 呼吸灯
        }
        
//        Delay10us(1);//延时缓冲,个人习惯,可加可不加
    }
}

这需要把流水灯和后呼吸灯的控制放在定时器中断中执行,在中断改变LED的状态或者亮度,然后再主循环中扫描按键,一个按键切换两种模式 另一个按键改变定时器中断频率。

提供参考链接【51单片机:独立按键控制LED灯】,期望对你有所帮助:https://blog.csdn.net/weixin_52300845/article/details/124317717
【博文内容以实例的形式详细讲解,分段分析,且内容和你的需求很相似】