使用IO口模拟PWM设计呼吸灯_硬件设计


《《《《《正文》》》》》



《硬件设计》

控制灯的IO口接芯片即可;

使用IO口模拟PWM设计呼吸灯_#define_02


《软件架构》

使用IO口模拟PWM设计呼吸灯_运行时间_03



《软件设计》

我的呼吸灯功能由2个函数实现,一个函数是IO模拟PWM产生波形;另一个函数是控制占空比的改变快慢及大小;他们之间用一个可更改的占空比变量联系;

可更改的占空比变量:

volatile uint16_t pwm_duty=0u;    //占空比


1、设计IO模拟PWM波形函数

该函数需要被周期调用,这样是为了可以对时间进行精确的计时,从而实现对占空比的控制,我选择100us的调用周期。

呼吸灯PWM周期的选定,也就是频率,我选择200hz,也就是5ms的周期,可根据实际的情况改变频率,当然前提是不能太低,太低会使led出现明显的闪烁现象;

根据上面100us的函数调用时间,实现5ms的周期的话需要周期计数值为50;这个数决定了你的PWM的可以分得的档次,如果是50,就只有50挡了,相当于最小改变占空比的数值为2%;如果是100,那就有100挡,最小改变占空比为1%;

//PWM周期宏定义 跟调用周期有关#define  BREATH_LEDPWM_PERIOD     50u  // 调用周期*50 = 100us*50 =5ms

具体函数:

#define  BREATH_LEDPWM_PERIOD     50u  void Led_BreathFunction(void){  static uint16_t led_BreathPwmCnt = 0u;  led_BreathPwmCnt++;      if(led_BreathPwmCnt > pwm_duty) //占空比分界点  {      DOORLED_1;//用户实际操作IO电平  }  else  {    DOORLED_0; //用户实际操作IO电平  }    if(led_BreathPwmCnt >= BREATH_LEDPWM_PERIOD) //一个PWM周期完成  {    led_BreathPwmCnt=0u;  }  }

当pwm_duty=25时,相对于周期计数值50,就是一半,即50%的占空比;本人实际测得的波形如下图:

使用IO口模拟PWM设计呼吸灯_运行时间_04

这里多说一句,我们会发现周期是5.013ms,多出了13us,这个就是我在《关于PWM的一些事》那篇文章说的,使用IO模拟PWM时,当高频率的时候,你不得不考虑IO操作电平时的时间,还有程序的运行时间;因此没特殊情况,不推荐使用IO口模拟PWM;本人也不推荐使用IO模拟PWM,所以我这里的程序也只是打个样,代码就不公布,需要的可以私下留言联系;后续会使用STM32的PWM模块实现呼吸灯,提供那一套代码;


使用IO口模拟PWM设计呼吸灯_io操作_05

2、设计改变占空比函数

决定呼吸快慢有2个因素,第一个因素是占空比改变的快慢,比如30ms或者40ms改变一次占空比;第二个因素是占空比改变的大小,比如一次改变占空比增加5%,或者10%等;

因此同样的,这个函数需要对时间的计数,也需要周期性调用;我使用2ms调用;30ms改变一次占空比,每次占空比改变2%(对应到50的PWM周期计数值,那就是1,这里50最小改变占空比大小为2%);

#define PwmChangePeriod   15  //占空比改变周期 调用周期*15 = 30ms#define PwmChangeDuty     1  //占空比改变大小  1/BREATH_LEDPWM_PERIOD = 2%void BreathLed_MainFunction(void){  static uint16_t Cnt_ = 0U//改变占空比周期计数值  static uint8_t  breathFlag =TRUE; //占空比递加减状态标志:TRUE:递加 FALSE:递减  Cnt_++;  if(Cnt_>PwmChangePeriod ) //到达改变占空比的时间,30ms  {    Cnt_ = 0U;    if(breathFlag) //占空比递加状态,就是变亮    {      pwm_duty+=PwmChangeDuty; //改变占空比      if(pwm_duty>=BREATH_LEDPWM_PERIOD)  //加到最大占空比则进入递减状态      {        breathFlag=FALSE;       }    }    else//占空比递减操作 就是变暗    {      pwm_duty-=PwmChangeDuty;//改变占空比      if(pwm_duty==0U)//递减到最小占空比则进入递加状态      {        breathFlag=TRUE;      }    }  }  }


《呼吸灯效果》

效果可能不好,这跟PWM可以分的档位有关,以及占空比改变的快慢、占空比改变的大小都有关,这个自己需要根据实际调试参数;




《《《《《END》》》》》

使用IO口模拟PWM设计呼吸灯_硬件设计