打印
[应用相关]

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

[复制链接]
908|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
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调制的呀

使用特权

评论回复
5
feiqi1| | 2022-1-13 21:53 | 只看该作者
这个没有脉宽调制模块吗?

使用特权

评论回复
6
xia00| | 2022-1-13 21:59 | 只看该作者
定时器1有三种工作模式,模模式是其中之一。

使用特权

评论回复
7
xyc1| | 2024-4-8 20:12 | 只看该作者
厉害

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

142

主题

1494

帖子

6

粉丝