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
【博文内容以实例的形式详细讲解,分段分析,且内容和你的需求很相似】