[活动专区] 【赛元95F】3、定时器+PWM的呼吸灯

[复制链接]
1708|4
 楼主| yang_alex 发表于 2020-4-8 11:40 | 显示全部楼层 |阅读模式
本帖最后由 yang_alex 于 2020-4-8 11:40 编辑

          只是让灯闪烁还是有点简单了,那我们就玩点稍微复杂的------呼吸灯。

          呼吸灯的简单原理就是用PWM波驱动LED,逐渐调大占空比,到达最大占空比后再逐渐调小占空比。

          赛元的SC95F861X系列MCU 提供了最多 8 路共用周期、单独可调占空比的 12 位 PWM。我们这里只用其中一路。PWM类型可设为中心对齐型或边沿对齐型,我们这里简单地采用边沿对齐型;PWM模式可设为独立模式或互补模式(对于需要设置死区的上下管驱动非常有用),我们这里只简单地采用独立模式。PWM还支持 故障检测功能,故障检测功能常应用于电机系统的防护,发现故障马上停止驱动,非常实用的一个功能,我们这里暂时用不上。

          先进行外设初始化和相关参数初始化。
  1. void main(void)
  2. {            
  3.        IO_Init();
  4.         
  5.       Timer_Init();
  6.         
  7.       PWM_Init();
  8.         
  9.       T_ms = 0;
  10.         
  11.       V_Duty = 0;

  12.       while(1);
  13. }

            IO外设初始化
  1. /*****************************************************
  2. *函数名称:void IO_Init(void)
  3. *函数功能:IO初始化
  4. *入口参数:void
  5. *出口参数:void
  6. *****************************************************/
  7. void         IO_Init(void)
  8. {
  9.        P4CON = 0xFF;  //设置P4为强推挽模式
  10.        P4PH  = 0x01;
  11. }
         
           定时器初始化
  1. /*****************************************************
  2. *函数名称:void Timer_Init(void)
  3. *函数功能:T0/T1/T2初始化
  4. *入口参数:void
  5. *出口参数:void
  6. *****************************************************/
  7. void Timer_Init(void)
  8. {
  9.       TMCON = 0X00;    //------111 ;Timer0、Tiemr1和Tiemr2选择时钟Fsys/12
  10.         
  11.       //T0设置
  12.       TMOD |= 0x01;                 //0000 0001;Timer0设置工作方式1
  13.       TL0 = (65536 - 7192)%256;    //时钟为Fsys/12,则溢出时间=7192*(1/Fsys);
  14.       TH0 = (65536 - 7192)/256;
  15.       TR0 = 0;
  16.       ET0 = 1;//定时器0允许
  17.       TR0 = 1;//打开定时器0
  18.         
  19.       EA = 1;        
  20. }

             定时器中断,用来定时调整PWM的占空比(先逐渐增大,后逐渐减小)
  1. /**************************************************
  2. *函数名称:void timer0/1/2/3/4() interrupt 1/3/5/13/14
  3. *函数功能:定时器中断产生方波
  4. *入口参数:void
  5. *出口参数:void
  6. **************************************************/
  7. void timer0() interrupt 1
  8. {
  9.     TL0 = (65536 - 7192)%256;
  10.     TH0 = (65536 - 7192)/256;
  11.         
  12.     T_ms ++;
  13.                
  14.     if(T_ms < 400)
  15.     {
  16.           V_Duty = V_Duty + 1;
  17.     }
  18.     else
  19.     {
  20.           V_Duty  = V_Duty - 1;
  21.     }
  22.                
  23.     if(T_ms == 800)
  24.     {
  25.           T_ms = 0;
  26.           V_Duty = 0;
  27.     }
  28. }

           PWM初始化.
  1. /*****************************************************
  2. *函数名称:void PWM_Init(void)
  3. *函数功能:PWM独立模式初始化
  4. *入口参数:void
  5. *出口参数:void
  6. *****************************************************/
  7. void PWM_Init(void)
  8. {
  9.       //设置了周期为100us的PWM波形
  10.       PWMMOD = 0x00;           //独立模式,边沿对齐

  11.       PWMCFG = 0xB1;           //7:开关  5-4:时钟源选择     3-0:周期设置高4位          10k----018F
  12.         
  13.       PWMCON = 0x8F;           //周期设置低8位,50us           10k----018F      
  14.         
  15.       PWMRD_41 = 0x8000 | V_Duty;     //开启PWM口,设置占空比
  16.         
  17.       IE1 |= 0x02;        //开启中断标志位
  18.         
  19.       EA = 1;
  20. }

           PWM中断处理程序,加载调整后的占空比参数.
  1. /*****************************************************
  2. *函数名称:void PWM_Interrup() interrupt 8
  3. *函数功能:PWM中断服务函数
  4. *入口参数:void
  5. *出口参数:void
  6. *****************************************************/
  7. void PWM_Interrup() interrupt 8
  8. {
  9.     if(PWMCFG & 0x40)
  10.     {
  11.         PWMCFG &= ~0x40;  //清除中断标志位
  12.         PWMRD_41 = 0x8000 | V_Duty;     //开启PWM口,设置占空比
  13.     }
  14. }

OK.大功告成,看看运行的效果吧。

led-breath.gif




海力小卢as 发表于 2020-4-9 18:41 | 显示全部楼层
很不错
qwe123zxc 发表于 2020-4-9 19:27 来自手机 | 显示全部楼层
可不可以用双向可控硅控制白炽灯
 楼主| yang_alex 发表于 2020-4-9 20:34 | 显示全部楼层
qwe123zxc 发表于 2020-4-9 19:27
可不可以用双向可控硅控制白炽灯

应该是可以的。不过要加一个过零检测电路。
鑫越电子 发表于 2020-4-10 09:57 | 显示全部楼层
学习学习,谢谢楼主分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则

35

主题

2239

帖子

9

粉丝
快速回复 在线客服 返回列表 返回顶部