玩转蓝牙4.0系列教程(第一季)-第三课 定时器比较输出(PWM波产生)
PWM波产生的方法有很多种,比如常见的软件延时引脚输出高低电平方法,利用定时器中断计数输出高低电平方法,这样的方法相信大家都用过,说起来比较好用,单效率太低,软件延时那个多写点程序,输出PWM频率就会改变,定时器中断效率太低,单片机一直在进入中断;今天为大家带来一种CC2540配置寄存器后就可以直接输出PWM的方法;即定时器比较中断方法;
首先得配置一下寄存器:
我们利用定时器1,CH1输出波形;硬件上为P0_3引脚,选择P0_3为第二功能
PERCFG |= 0x33; // Move USART1&2 to alternate2 location so that T1 is
配置一下引脚的选择和输出方向
P0DIR|= BV(3)|BV(4)|BV(5);//设置pwm端口为输出
P0SEL|= BV(3)|BV(4)|BV(5);//设置pwm端口为外设端口,非gpio
配置输出方式
T1CTL = 0x0e; // Div = 128, CLR, MODE = module
T1CCTL1 = 0x1c; // IM = 0; CMP = Clear output on compare; Mode = Compare
T1CCTL2 = 0x1c; // IM = 0; CMP = Clear output on compare; Mode = Compare
T1CCTL3 = 0x1c; // IM = 0, CMP = Clear output on compare; Mode = Compare
T1CNTL = 0; // Reset timer to 0;
T1CNTH = 0; // Reset timer to 0;
输出的波形示波器显示:示波器参数:10ms. 1V
源代码:
/**************************************************
** 本程序只供学习使用,未经作者许可,不得用于其它任何用途
** 蓝牙4.0底板开发板
** 作者: shizhe
** 创始时间:2014-05-08
** 修改人:shizhe
** 修改时间:2014-05-08
** 修改人:shizhe
** 修改时间:2014-05-08
** 描述:
** 定时器1比较输出PWM
** 版权所有,盗版必究。
** Copyright(C) 联控智能 2014-2020
** All rights reserved
*************************************************/
#include<ioCC2540.h>
#define uint unsigned int
#define uchar unsigned char
#define BV(n) (1 << (n))
void T1_Init(void)//系统默认为16M
{
//设置pwm端口为输出
P0DIR|= BV(3)|BV(4)|BV(5);
//设置pwm端口为外设端口,非gpio
P0SEL|= BV(3)|BV(4)|BV(5);
//由于uart等会占用我们当前使用的pwm端口,因此需要将uart等重映射到别的端口去。
PERCFG |= 0x33; // Move USART1&2 to alternate2 location so that T1 is visible
T1CTL = 0x0e; // Div = 128, CLR, MODE = module
T1CCTL1 = 0x1c; // IM = 0; CMP = Clear output on compare; Mode = Compare
T1CCTL2 = 0x1c; // IM = 0; CMP = Clear output on compare; Mode = Compare
T1CCTL3 = 0x1c; // IM = 0, CMP = Clear output on compare; Mode = Compare
T1CNTL = 0; // Reset timer to 0;
T1CNTH = 0; // Reset timer to 0;
//必须设置,否则定时器不工作
T1CCTL0 = 0x1C; // IM = 1, CMP = Clear output on compare; Mode = Compare
T1CC0H = 0x07; // Ticks = 375 (2.4ms)
T1CC0L = 0XF8; // Ticks = 375 (2.4ms)
T1CC1H = 0x03; // Ticks = 375 (1,5ms initial duty cycle)
T1CC1L = 0Xc0;
T1CC2H = 0x03; // Ticks = 375 (1,5ms initial duty cycle)
T1CC2L = 0Xc0;
T1CC3H = 0x03; // Ticks = 375 (1,5ms initial duty cycle)
T1CC3L = 0Xc0;
EA=1;
IEN1 |= 0x02; // Enable T1 cpu interrupt
}
void main(void)
{
T1_Init();
while(1)
{
}
}