【CC2530入门教程-强化练习A】利用脉宽调制实现呼吸灯

2019-07-14 23:50发布

本帖最后由 ohy3686 于 2017-10-19 14:58 编辑

【CC2530入门教程-强化练习A】利用脉宽调制实现呼吸灯
硬件背景LED1灯连接到CC2530的P1_0引脚。
题目要求:利用定时器器1的模模式,实现0.1ms的间隔定时,并由此产生PWM信号输出,实现呼吸灯,
           即LED1灯从暗逐级变亮,当达到最亮时,又重新从暗逐级变亮,如此往复。
实现思路
1. 定义端口初始化函数Init_Port(),初始化必要的I/O端口。
2. 定义定时器1初始化函数Init_Timer1(),使用内部的16MHz晶振的8分频作为时钟输入信号,采用模模式,实现0.1ms的间隔定时。
3. 通过对间隔定时的累计,可以实现一个周期为10ms,占空比可变化的脉宽调制信号,由其控制LED1灯的亮度。
4. 定时中断服务函数Timer1_Sevice()是程序的核心,全部PWM信号变化和呼吸灯逻辑控制,均在这里实现。
5. 在main()函数中,初始化端口和定时器,进入死循环就可以实现呼吸灯的功能了。
参考源码:
  1. #include "ioCC2530.h"
  2. #define  LED1   P1_0

  3. unsigned char pwm_period = 100; //定义PWM的周期
  4. unsigned char pwm_duy = 90;     //定义PWM的占空比
  5. unsigned char t_count = 0;      //间隔定时次数累计

  6. /*==================端口初始化函数======================
  7. 功能:初始化LED1和SW按键
  8.       将P1_0设置为通用I/O端口的输出模式
  9.       关闭LED1灯
  10. 设计:广东职业技术学院  欧浩源
  11. 时间:2017年10月19日
  12. ========================================================*/
  13. void Init_Port()
  14. {
  15.   P1SEL &= ~0x01;  //将P1_0设置为通用I/O端口
  16.   P1DIR |= 0x01;   //将P1_0设置为输出方式
  17.   LED1 = 1;        //输出1--关灯,输出0--开灯
  18. }

  19. /*=================定时器1初始化函数=====================
  20. 功能:初始化定时器1
  21.       使用内部16MHz晶振,定时周期1ms,
  22.       使用模模式,开启通道0的输出比较模式,
  23.       分频系数8,打开相应的定时中断
  24. 设计:广东职业技术学院  欧浩源
  25. 时间:2017年10月19日
  26. ========================================================*/
  27. void Init_Timer1()
  28. {
  29.   /*=内部16MHz晶振8分频定时0.1ms的最大计数值为0x00c8=*/
  30.   T1CC0L = 0xc8;    //设置最大计数值的低8位
  31.   T1CC0H = 0x00;    //设置最大计数值的高8位
  32.   T1CCTL0 |= 0x04;  //开启通道0的输出比较模式
  33.   T1IE = 1;         //使能定时器1中断
  34.   T1OVFIM = 1;      //使能定时器1溢出中断
  35.   EA = 1;           //使能总中断
  36.   T1CTL = 0x06;     //分频系数是8,模模式
  37. }

  38. /*================定时器1中断服务函数====================
  39. 功能:1ms间隔定时中断服务函数
  40.       对间隔定时次数进行累加,即t_count++
  41.       t_count < pwm_duy, 输出高电平
  42.       pwm_duy < t_count < pwm_period, 输出低电平
  43.       t_count = pwm_period,t_count清0,输出高电平
  44.       每完成一个PWM改变一个占空比,实现呼吸灯
  45. 设计:广东职业技术学院  欧浩源
  46. 时间:2017年10月19日
  47. ========================================================*/
  48. #pragma vector = T1_VECTOR
  49. __interrupt void Timer1_Sevice()
  50. {
  51.   T1STAT &= ~0x01;        //清除定时器1通道0中断标志
  52.   t_count++;              //对间隔定时次数进行累加
  53.   if(t_count < pwm_duy)            //高电平周期到
  54.   {
  55.     LED1 = 1;                     
  56.   }
  57.   else if(t_count < pwm_period)   //低电平周期到
  58.   {
  59.     LED1 = 0;                     
  60.   }
  61.   else                  //准备开始下一个PWM输出
  62.   {
  63.     LED1 = 1;
  64.     t_count = 0;        //间隔定时累加清0
  65.     pwm_duy--;
  66.     if(pwm_duy == 1)
  67.     {
  68.       pwm_duy = 90;
  69.     }
  70.   }
  71. }

  72. /*=====================主函数===========================*/
  73. void main()
  74. {
  75.   Init_Port();        //初始化I/O端口
  76.   Init_Timer1();      //初始化定时器1
  77.   while(1);
  78. }
复制代码


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。