【CC2530入门教程-强化练习B】利用PWM实现灯光亮度调节

[复制链接]
 楼主| ohy3686 发表于 2017-10-19 14:56 | 显示全部楼层 |阅读模式
本帖最后由 ohy3686 于 2017-10-19 14:58 编辑

【CC2530入门教程-强化练习B】利用PWM实现灯光亮度调节


硬件背景LED1灯连接到CC2530的P1_0引脚,SW按键连接到CC2530的P0_1引脚。
题目要求:用定时器器1的模模式,实现0.1ms的间隔定时,并由此产生PWM信号输出,通过SW按键控制PWM占空比的变化,
                    实现LED1灯光从暗逐渐到亮,再从亮逐渐到暗的亮度控制。实现思路:
1. 定义必要的延时函数Delay()和端口初始化函数Init_Port(),在端口初始化函数中,初始化LED1灯和SW按键的相关端口寄存器。
2. 定义定时器1初始化函数Init_Timer1(),使用内部的16MHz晶振的8分频作为时钟输入信号,采用模模式,实现0.1ms的间隔定时。
3. 在定时中断服务函数Timer1_Sevice()中,实现PWM信号输出的相关程序。
4. 设计键盘扫描程序Scan_Keys(),实现PWM占空比的变化控制。
5. 在main()函数中,通过扫描按键控制PWM的占空比,实现对LED1的亮度控制。
参考源码:



  1. #include "ioCC2530.h"
  2. #define  LED1   P1_0
  3. #define  SW     P0_1

  4. unsigned char pwm_period = 100; //定义PWM的周期
  5. unsigned char pwm_duy = 90;     //定义PWM的占空比
  6. unsigned char t_count = 0;      //间隔定时次数累计
  7. unsigned char flag_dir = 0;     //占空比变化方向标志
  8. /*======================延时函数==========================
  9. 功能:根据输入参数实现延时
  10. 设计:广东职业技术学院  欧浩源
  11. 时间:2017年10月19日
  12. ========================================================*/
  13. void Delay(unsigned int time)
  14. {
  15.   while(time--);
  16. }
  17. /*==================端口初始化函数======================
  18. 功能:初始化LED1和SW按键
  19.       将P1_0设置为通用I/O端口的输出模式
  20.       将P0_1设置为通用I/O端口的输入模式,上拉
  21.       关闭LED1灯
  22. 设计:广东职业技术学院  欧浩源
  23. 时间:2017年10月19日
  24. ========================================================*/
  25. void Init_Port()
  26. {
  27.   P1SEL &= ~0x01;  //将P1_0设置为通用I/O端口
  28.   P1DIR |= 0x01;   //将P1_0设置为输出方式
  29.   P0SEL &= ~0x02;  //将P0_1设置为通用I/O端口
  30.   P0DIR &= ~0x02;  //将P0_1设置为输入方式
  31.   LED1 = 1;        //输出1--关灯,输出0--开灯
  32. }

  33. /*=================定时器1初始化函数=====================
  34. 功能:初始化定时器1
  35.       使用内部16MHz晶振,定时周期1ms,
  36.       使用模模式,开启通道0的输出比较模式,
  37.       分频系数8,打开相应的定时中断
  38. 设计:广东职业技术学院  欧浩源
  39. 时间:2017年10月19日
  40. ========================================================*/
  41. void Init_Timer1()
  42. {
  43.   /*=内部16MHz晶振8分频定时0.1ms的最大计数值为0x00c8=*/
  44.   T1CC0L = 0xc8;    //设置最大计数值的低8位
  45.   T1CC0H = 0x00;    //设置最大计数值的高8位
  46.   T1CCTL0 |= 0x04;  //开启通道0的输出比较模式
  47.   T1IE = 1;         //使能定时器1中断
  48.   T1OVFIM = 1;      //使能定时器1溢出中断
  49.   EA = 1;           //使能总中断
  50.   T1CTL = 0x06;     //分频系数是8,模模式
  51. }

  52. /*================定时器1中断服务函数====================
  53. 功能:1ms间隔定时中断服务函数
  54.       对间隔定时次数进行累加,即t_count++
  55.       t_count的计数值到达pwm_duy,高电平变为低电平
  56.       t_count的计数值到达pwm_period,低电平变为高电平
  57.       一个PWM周期结束,t_count清0 ,开始下一个PWM计数
  58. 设计:广东职业技术学院  欧浩源
  59. 时间:2017年10月19日
  60. ========================================================*/
  61. #pragma vector = T1_VECTOR
  62. __interrupt void Timer1_Sevice()
  63. {
  64.   T1STAT &= ~0x01;        //清除定时器1通道0中断标志
  65.   t_count++;              //对间隔定时次数进行累加
  66.   if(t_count == pwm_duy)           //高电平周期到
  67.   {
  68.     LED1 = 0;                      //输出低电平
  69.   }
  70.   else if(t_count == pwm_period)  //低电平周期到
  71.   {
  72.     LED1 = 1;                     //输出高电平
  73.     t_count = 0;                  //间隔定时累加清0
  74.   }
  75. }

  76. /*==================按键扫描处理函数======================
  77. 功能:扫描SW按键是否按下,如有按下信号先做去抖动处理
  78.       确认为SW按键动作后,
  79.       改变PWM的占空比,每次减少10个单位
  80.       当减少到占空比的边沿时,每次增加10个单位
  81.       如此往复,实现PWM占空比的来回变化
  82.       等待按键松开后,退出扫描程序
  83. 设计:广东职业技术学院  欧浩源
  84. 时间:2017年10月19日
  85. ========================================================*/
  86. void Scan_Keys()
  87. {
  88.   if(SW == 0)
  89.   {
  90.     Delay(100);             //按键去抖动处理
  91.     if(SW == 0)
  92.     {
  93.       if(flag_dir == 0)
  94.       {
  95.         pwm_duy -= 10;        //改变PWM的占空比
  96.         if(pwm_duy == 10)     //如果占空比到达边沿
  97.         {
  98.           flag_dir = 1;       //改变占空比的变化方向
  99.         }
  100.       }
  101.       else if(flag_dir == 1)
  102.       {
  103.         pwm_duy += 10;        //改变PWM的占空比
  104.         if(pwm_duy == 90)     //如果占空比到达边沿
  105.         {
  106.           flag_dir = 0;       //改变占空比的变化方向
  107.         }
  108.       }
  109.       while(SW == 0);
  110.     }
  111.   }
  112. }

  113. /*=====================主函数===========================*/
  114. void main()
  115. {
  116.   Init_Port();        //初始化I/O端口
  117.   Init_Timer1();      //初始化定时器1
  118.   while(1)
  119.   {
  120.     Scan_Keys();      //扫描按键
  121.   }
  122. }




dirtwillfly 发表于 2017-10-19 17:16 | 显示全部楼层
感谢分享
soodesyt 发表于 2017-11-6 22:16 | 显示全部楼层
soodesyt 发表于 2017-11-6 22:18 | 显示全部楼层
这个实现远程电灯控制很简单。
 楼主| ohy3686 发表于 2017-11-6 23:14 | 显示全部楼层
soodesyt 发表于 2017-11-6 22:18
这个实现远程电灯控制很简单。

灯控的程序并不难
jstgotodo 发表于 2017-11-8 16:39 | 显示全部楼层
iamaiqiyi 发表于 2017-11-8 16:39 | 显示全部楼层
这个的时钟速度是多大?
jstgotodo 发表于 2017-11-8 16:46 | 显示全部楼层
定时器输出PWM功能。
iamaiqiyi 发表于 2017-11-8 16:46 | 显示全部楼层
定时器频率太大,会不会影响到其他功能?
 楼主| ohy3686 发表于 2017-11-9 09:29 | 显示全部楼层
iamaiqiyi 发表于 2017-11-8 16:46
定时器频率太大,会不会影响到其他功能?

只要功能不太多,一般不会影响。
 楼主| ohy3686 发表于 2017-11-9 09:31 | 显示全部楼层
iamaiqiyi 发表于 2017-11-8 16:39
这个的时钟速度是多大?

系统时钟16MHz
定时器时钟2MHz
PWM频率10KHz
xiaoyaodz 发表于 2017-11-9 22:12 | 显示全部楼层
ohy3686 发表于 2017-11-9 09:31
系统时钟16MHz
定时器时钟2MHz
PWM频率10KHz

时钟速度可以。
febgxu 发表于 2017-11-9 22:13 | 显示全部楼层
楼主开发个板子吧。
xiaoyaodz 发表于 2017-11-9 22:16 | 显示全部楼层
ohy3686 发表于 2017-11-9 09:31
系统时钟16MHz
定时器时钟2MHz
PWM频率10KHz

机器周期是多大?
febgxu 发表于 2017-11-9 22:16 | 显示全部楼层
设计一个复杂的开发板,功能齐全点。
 楼主| ohy3686 发表于 2017-11-10 12:49 | 显示全部楼层
febgxu 发表于 2017-11-9 22:16
设计一个复杂的开发板,功能齐全点。

目前正在做一款CC2530的开发板
功能会比较全一些,也兼容市面上部分开发板的接口
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:广东职业技术学院 欧浩源(ohy3686@foxmail.com)    [Zigbee技术&物联网应用] 群:168225322    [技术交流微信]:gzyohy (暗号:宝塔镇河妖)

322

主题

899

帖子

3548

粉丝
快速回复 在线客服 返回列表 返回顶部
个人签名:广东职业技术学院 欧浩源(ohy3686@foxmail.com)    [Zigbee技术&物联网应用] 群:168225322    [技术交流微信]:gzyohy (暗号:宝塔镇河妖)

322

主题

899

帖子

3548

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