MSP432P401R基础使用
六、定时器A PWM模式
(一)计数模式
- 增计数模式
需要设置CCR0比较值寄存器0,CCR0确定定时器周期,可以将CCR0理解为STM32的ARR自动重装载值,定时器中断周期的计算公式也是通用的:Ttimer_a= C l k D i v × ( C C R 0 + 1 ) f c l k \quad {ClkDiv×(CCR0+1)\over f~clk~} f clk ClkDiv×(CCR0+1)【时钟分频乘以计数值(CCR0+1)的和除以时钟频率】
ClkDiv ∈ [1, 8] ∪ {10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64 };
这里与STM32不同,是固定的
- 增减计数模式
从0开始计数到CCR0递减为0
(二)输出模式
增计数模式 增减计数模式
定时器A有7种输出模式,但常用的只有两种
-
Output Mode 2:Toggle/Reset
当计时器计数到TAxCCRn值时,输出切换。当计时器计数到TAxCCR0值时,它被重置。
-
Output Mode 6:Toggle/Set
当计时器计数到TAxCCRn值时,输出切换。当计时器计数到TAxCCR0值时设置。
详见msp432p401r第791页
1.增计数模式:
定时器A从0计数到比较值1(CCR1)时,模式6输出高电平,之后比较值1计数到比较值0(CCR0)时,输出为低电平
比较值0是确定了整个定时器的周期
当选择输出模式2时,可以看到输出是相反的。
2.增减计数模式:
模式2和模式6配合后能生成带死区的互补PWM
一个定时器A能生成2路的带死区的互补PWM
(三)定时器A输出通道资源
带有PM是支持端口重映射的意思
(四)库函数
- 初始化定时器为PWM模式
Timer_A_generatePWM(TIMER_Ax_BASE, &TimAx_PWMConfig);
- 改变比较值(占空比/周期)
Timer_A_setCompareValue(TIMER_Ax, COMPARE_REGISTER_x, CCR);
(五)一般配置步骤
- 配置时钟
- 配置GPIO复用
- 配置结构体
- 初始化定时器
(六)PWM驱动舵机
timA.h
#ifndef __RNA_TIMA_H
#define __RNA_TIMA_H
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
void TimA1_PWM_Init(uint16_t ccr0, uint16_t psc);
#endif
timA.c
#include "timA.h"
void TimA1_PWM_Init(uint16_t ccr0, uint16_t psc)
{
/*初始化引脚*/
MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P7, GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);
Timer_A_PWMConfig TimA1_PWMConfig;
/*定时器PWM初始化*/
TimA1_PWMConfig.clockSource = TIMER_A_CLOCKSOURCE_SMCLK; //时钟源
TimA1_PWMConfig.clockSourceDivider = psc; //时钟分频 范围1-64
TimA1_PWMConfig.timerPeriod = ccr0; //自动重装载值(ARR)
TimA1_PWMConfig.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_1; //通道一 (引脚定义)
TimA1_PWMConfig.compareOutputMode = TIMER_A_OUTPUTMODE_TOGGLE_SET; //输出模式
TimA1_PWMConfig.dutyCycle = ccr0; //这里是改变占空比的地方 默认100%
MAP_Timer_A_generatePWM(TIMER_A1_BASE, &TimA1_PWMConfig); /* 初始化比较寄存器以产生 PWM1 */
}
main.c
#include "sysinit.h"
#include "usart.h"
#include "delay.h"
#include "timA.h"
/*
* 定时器PWM周期:
*`
* T_timer_a = CLKDIV * (CCR0 + 1) / f_clk
* = 48 * (19999 + 1) / 48000000
* = 0.02s = 50Hz
*/
#define CLKDIV 48 // 时钟源分频
#define CCR0 19999 // 比较值0
#define CCR1_MIN 499 // ( 499 + 1) / (19999 + 1) = 500 / 20000 = 2.5%
#define CCR1_MAX 2499 // (2499 + 1) / (19999 + 1) = 2500 / 20000 = 12.5%
int main(void)
{
bool dir = 1;
uint16_t i = CCR1_MIN;
SysInit(); //第3讲 时钟配置
delay_init(); //第4讲 滴答延时
TimA1_PWM_Init(CCR0, CLKDIV); //第8讲 定时器A PWM
while (1)
{
if (dir)
i++;
else
i--;
if (i == CCR1_MAX)
{
dir = 0;
delay_ms(50);
}
else if (i == CCR1_MIN)
{
dir = 1;
delay_ms(50);
}
MAP_Timer_A_setCompareValue(TIMER_A1_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_1, i);
delay_us(600);
}
}