干货分享,废话不多说,贴代码

#define BreatheMax 280
void BreatheLed(void)
{static unsigned char B_Reverse= 0;static int Low_Time = 0;static int tem = 0;if(!B_Reverse)   //渐亮{tem++;                 //该变量会从0~BreatheMax循环,代表PWM的周期if(tem > BreatheMax){tem = 0;Low_Time++;                 //每BreatheMax * 10us自加1if(Low_Time >= BreatheMax) //限制加到BreatheMax之后跳到渐灭{B_Reverse = 1;    }}  }else       //渐灭{tem++;if(tem > BreatheMax){tem = 0;Low_Time--;        //每BreatheMax * 10us自减1if(Low_Time < 0) //限制减到0之后回到渐亮{B_Reverse = 0;}} }/*以渐亮为例:函数是10us周期性调用tem: 从0~BreatheMax循环递增BreatheMax - Low_Time :随着 Low_Time 的增加,因为BreatheMax是固定的,所以BreatheMax - Low_Time会减少例如: Low_Time = 60;BreatheMax - Low_Time = 220,则下列语句执行的效果就是:有220 * 10us 的时间语句条件不成立,执行 (LED0 = 1)60*10us  的时间语句条件成立,  执行 (LED0 = 0)灯是低电平点亮,由于高电平时间比低电平多,所以呈现灯较暗的现象,反之则亮*/(tem > BreatheMax - Low_Time)?(LED0 = 0):(LED0 = 1); //如果?前条件成立,执行(LED0 = 0),否则执行(LED0 = 1)
}

如需移植,则将LED0替换为自己对应的IO口就行,改变BreatheMax的值可以改变呼吸灯呼吸的快慢,如果能看到呼吸灯在闪烁,说明设置的值太大或者是周期性调用的时间太慢 。如果周期性调用的时间慢,则BreatheMax的值也要相应的减小。可以中断调用,该函数不会阻塞运行

  • 如果你的灯是高电平点亮,将(tem > BreatheMax - Low_Time)?(LED0 = 0):(LED0 = 1) 改为:(tem > BreatheMax - Low_Time)?(LED0 =1):(LED0 = 0)即可,这条语句可以用if-else替代

如有疑问或更好的实现方式,麻烦评论区留言……

-------------------优雅的分割线-------------------------------

继呼吸灯之后,可删减成IO模拟PWM输出,话不多说,附代码

/*功能:IO模拟Pwm注:需周期性调用,因pwm输出的周期受调用时间的影响,若调用时间变化,则pwm也会随之变化Cycle:取值范围0-100,注:就算入口参数填入100,IO口也不会完全输出高电平,还是会输出低电平
*/
unsigned char R_ShiftGear;
unsigned char R_ShiftDelay;
#define PwmCycle 100 //本例是10ms周期调用,所以pwm输出周期为 10ms * 100 = 1000ms,可根据需求修改
void Pwm_duty(unsigned char duty)
{switch (R_ShiftGear){case 0:Pin_Out_ON; //定义IO口高电平为开if (++R_ShiftDelay >= duty) //Pwm输出高电平时间{R_ShiftDelay = 0;//计数清零R_ShiftGear = 1; //跳转到case 1}break;case 1:Pin_Out_OFF;  //因此语句,从case0 到 case1,肯定会有一小段低电平时间,本例中这个bug不影响使用if (++R_ShiftDelay >= (PwmCycle - duty)) {R_ShiftDelay = 0;R_ShiftGear = 0;}break;default:break;}
}

2022.8.23更新:

关于模拟pwm不能输出全高电平,优雅的解决方式,附上修改后的代码

unsigned char Pwm_Index;
unsigned char R_Shift_Count;
#define PwmCycle 100 //本例是10ms周期调用,所以pwm输出周期为 10ms * 100 = 1000ms,可根据需求修改
void Pwm_duty(unsigned char duty)
{switch (Pwm_Index){case 0:  if (++R_Shift_Count>= duty) //Pwm输出高电平时间{R_Shift_Count= 0;//计数清零Pwm_Index= 1; //跳转到case 1Pin_Out_OFF;}else{Pin_Out_ON; //定义IO口高电平为开}break;case 1:if (++R_Shift_Count>= (PwmCycle - duty)) {R_ShiftDelay = 0;Pwm_Index= 0;Pin_Out_ON; }else{Pin_Out_OFF;}break;default:Pwm_Index = 0;break;}
}

---------------------------------------------------------2022.3.29更新分割线-------------------------------------------------

第一版的呼吸灯不是很好理解,并且用起来也不方便,经优化,并实际应用之后,感觉效果还行。分享给有需要的

#define BreatheMax 150
bool Breathe_Status;
unsigned int Breathe_Timer_Count = 0;
//该函数最好中断调用,效果最好,主函数调用呼吸效果有可能会出现不连贯,主要原因是因为中断会打断。经实验,定时器100us中断调用效果还行
void BreatheLed_IO_Ctl(void)
{static unsigned int CycleCount = 0;if (Breathe_Status) {if (++CycleCount > BreatheMax){CycleCount = 0;}if (CycleCount >= (BreatheMax - Breathe_Timer_Count)){LED1_ON();}else{LED1_OFF();}}else{CycleCount = 0;}
}
//该函数在主函数中任意调用,实际运用中10ms调用效果还行,以实际需求为准
void BreatheLed_Time_Ctl(void)
{static bool BreatheReverse;if (Breathe_Status) //该标志是开启时呼吸灯置1,或者替换成自定义标志位{if (!BreatheReverse){if (++Breathe_Timer_Count >= BreatheMax) //限制加到BreatheMax之后跳到渐灭{BreatheReverse = 1;}}else{if (Breathe_Timer_Count){Breathe_Timer_Count--;}else{//减到0之后回到渐亮BreatheReverse = 0;}//也可以不减到0就切换状态,需加判断,判断Breathe_Timer_Count的值}}else{Breathe_Timer_Count = 0;BreatheReverse = 0;}
}

呼吸灯程序(非阻塞)相关推荐

  1. dsp呼吸灯C语言编程,DSP28335 呼吸灯程序

    DSP28335呼吸灯程序 //########################################################################### // // FI ...

  2. 模拟IO口简单呼吸灯程序

    定义一个0.1ms 的时钟周期性调用下面C函数 /*呼吸灯程序*/ void BreathingLamp(void) {static uint8_t LEDTimeCount=0;static uin ...

  3. 基于qtLED呼吸灯程序(多线程控制)---全CSDN独家

    本次实验是基于基于qtLED呼吸灯程序(多线程控制),大家都知道呼吸灯都是用pwm波来控制输出电压的大小来控制呼吸灯的一闪一灭来实现呼吸的效果,开呼吸灯程序免不了用while死循环,嵌入式必备程序wh ...

  4. keil5生成一个单片机led呼吸灯程序

    对于生成单片机 LED 呼吸灯程序,您可以以下这样做: 打开 Keil 5 软件,创建一个新项目. 选择您使用的单片机类型和板子,按照向导配置项目. 在程序代码中包含所需的头文件和定义. 使用 for ...

  5. wringPi 初始化GPIO 为上拉_玩转GPIO之PWM点亮呼吸灯(非树莓派)

    在这篇文章,我介绍了基于逸宸电子开发的总线适配器来点亮LED灯的基本方法! myastrotong:玩转GPIO之点灯(非树莓派)​zhuanlan.zhihu.com 这款总线适配器的介绍见这里: ...

  6. stm32呼吸灯程序_学习STM32从点灯开始!

    前言 学STM32我们从点灯开始,学Linux驱动我们自然也要点个灯来玩玩,尽量在从这些基础例程中榨取知识,细抠.细抠,为之后更复杂的知识打好基础. 与硬件无关的LED驱动 回顾hello驱动程序,我 ...

  7. stm32呼吸灯程序_STM32裸机开发基础篇02点亮LED

    前言 上一节,我们完成了STM32单片机开发环境的搭建,本节我们正式学习STM32单片机,编程语言的学习,通常是从第一个"hello world"开始,而点灯实验便是单片机学习的开 ...

  8. C语言开定时器做呼吸灯程序,[求助]呼吸灯的编程思路(C语言)

    /*************************************************************** * 程序说明:使用P3.2和P3.4来控制P0端口的LED灯,达到手动 ...

  9. 野火stm32呼吸灯程序_说一说STM32启动过程

    STM32上电后是怎么启动的? main函数之前单片机都做了些什么? 带着这些疑问我们开始进入游戏..... 首先,开局一张图,过程全靠编,如有说错的地方望能指正 启动大致流程 1- 上电启动或者硬件 ...

  10. C语言开定时器做呼吸灯程序,简单的基于51单片机定时器上呼吸灯程序

    #include #define ufloat unsigned float #define uchar  unsigned char #define uint   unsigned int ucha ...

最新文章

  1. 2018,愿跟大家一起成长!
  2. Docker for Linux 安装
  3. 关于Linux服务器配置java环境遇到的问题
  4. 深度学习中张量flatten处理(flatten,reshape,reduce)
  5. Nodejs【单机】多进程模式集群
  6. python meshgrid_torch.meshgrid()和np.meshgrid()的区别
  7. 流程流转相关业务与流转的分离
  8. C#小游戏—钢铁侠VS太空侵略者
  9. 信号集操作函数,信号未决、阻塞、递达
  10. 讯飞 tts 9.0 app_讯飞B1录音笔,到底值不值得买?
  11. android 经纬度距离计算器,经纬度距离角度计算软件|经纬度距离角度计算器(geography) v2.0免费版_星星软件园...
  12. IntelliJ IDEA 下载安装以及破解码大集合
  13. 计算机多媒体简历,[计算机个人简历模板范文]计算机多媒体专业个人简历
  14. axure能做剪切蒙版吗_***自动售货机能做吗
  15. 初中毕业也能月薪过万!5个质量极高的教程网站,免费献给你
  16. C语言getc函数没错不管用,对比C语言中getc()函数和ungetc()函数的使用
  17. Container killed by YARN for exceeding memory limits
  18. euecwglupnwydnp
  19. oracle中drop和delete,oracle中delete drop truncate的用法和区别
  20. 表情识别(七)--面部表情识别阶段综述(2018.4)

热门文章

  1. Bartender条码打印软件,提示30天以后该软件将会过期
  2. 百度网页注册HTML代码
  3. Audio Jungle宣传专题片头音乐AE模板专用配乐合集-永久更新
  4. 2016最新PHP燕十八系统实战入门网站视频教程
  5. 【数学建模】模糊数学模型详解
  6. win7藏文打印部分文字乱码问题处理
  7. java actionsupport_【JAVA学习】struts2 中 Actionsupport 的作用
  8. struts2继承ActionSupport
  9. 圆柱体积怎么算立方公式_圆柱体体积计算公式?
  10. 反编译OD工具OllyDBG 2.0.1下载