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

[复制链接]
 楼主| shashaa 发表于 2022-1-13 21:27 | 显示全部楼层 |阅读模式
硬件背景: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()函数中,初始化端口和定时器,进入死循环就可以实现呼吸灯的功能了。
参考源码:
复制
#include "ioCC2530.h"

#define  LED1   P1_0



unsigned char pwm_period = 100; //定义PWM的周期

unsigned char pwm_duy = 90;     //定义PWM的占空比

unsigned char t_count = 0;      //间隔定时次数累计



/*==================端口初始化函数======================

功能:初始化LED1和SW按键

      将P1_0设置为通用I/O端口的输出模式

      关闭LED1灯

设计:广东职业技术学院  欧浩源

时间:2017年10月19日

========================================================*/

void Init_Port()

{

  P1SEL &= ~0x01;  //将P1_0设置为通用I/O端口

  P1DIR |= 0x01;   //将P1_0设置为输出方式

  LED1 = 1;        //输出1--关灯,输出0--开灯

}



/*=================定时器1初始化函数=====================

功能:初始化定时器1

      使用内部16MHz晶振,定时周期1ms,

      使用模模式,开启通道0的输出比较模式,

      分频系数8,打开相应的定时中断

设计:广东职业技术学院  欧浩源

时间:2017年10月19日

========================================================*/

void Init_Timer1()

{

  /*=内部16MHz晶振8分频定时0.1ms的最大计数值为0x00c8=*/

  T1CC0L = 0xc8;    //设置最大计数值的低8位

  T1CC0H = 0x00;    //设置最大计数值的高8位

  T1CCTL0 |= 0x04;  //开启通道0的输出比较模式

  T1IE = 1;         //使能定时器1中断

  T1OVFIM = 1;      //使能定时器1溢出中断

  EA = 1;           //使能总中断

  T1CTL = 0x06;     //分频系数是8,模模式

}



/*================定时器1中断服务函数====================

功能:1ms间隔定时中断服务函数

      对间隔定时次数进行累加,即t_count++

      t_count < pwm_duy, 输出高电平

      pwm_duy < t_count < pwm_period, 输出低电平

      t_count = pwm_period,t_count清0,输出高电平

      每完成一个PWM改变一个占空比,实现呼吸灯

设计:广东职业技术学院  欧浩源

时间:2017年10月19日

========================================================*/

#pragma vector = T1_VECTOR

__interrupt void Timer1_Sevice()

{

  T1STAT &= ~0x01;        //清除定时器1通道0中断标志

  t_count++;              //对间隔定时次数进行累加

  if(t_count < pwm_duy)            //高电平周期到

  {

    LED1 = 1;                     

  }

  else if(t_count < pwm_period)   //低电平周期到

  {

    LED1 = 0;                     

  }

  else                  //准备开始下一个PWM输出

  {

    LED1 = 1;

    t_count = 0;        //间隔定时累加清0

    pwm_duy--;

    if(pwm_duy == 1)

    {

      pwm_duy = 90;

    }

  }

}



/*=====================主函数===========================*/

void main()

{

  Init_Port();        //初始化I/O端口

  Init_Timer1();      //初始化定时器1

  while(1);

}
qiangweii 发表于 2022-1-13 21:35 | 显示全部楼层
定时调试占用资源太多了吧。
litengg 发表于 2022-1-13 21:39 | 显示全部楼层
这个主要是调节PWM脉冲的占空比的。。
androidbus 发表于 2022-1-13 21:40 | 显示全部楼层
看来这个主要还是采用PWM调制的呀
feiqi1 发表于 2022-1-13 21:53 | 显示全部楼层
这个没有脉宽调制模块吗?
xia00 发表于 2022-1-13 21:59 | 显示全部楼层
定时器1有三种工作模式,模模式是其中之一。
xyc1 发表于 2024-4-8 20:12 | 显示全部楼层
厉害
您需要登录后才可以回帖 登录 | 注册

本版积分规则

142

主题

1494

帖子

6

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

142

主题

1494

帖子

6

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