开发板型号:MSP432P401r
今日得以继续我的MSP432电赛速通之路,文首提供本次学习实践项目文件。
注:我笔记实践都是从原始空项目工程文件开始配置的。
有道是 —_—_—_—_—
“山无重数周遭碧,花不知名分外娇” “曲中人不见,江上数峰青” .........
连绵不绝的山峦,起伏有序,高峰紧薄低谷,诗意酝在其中。
像极了我们今日要学习的——定时器PWM输出
目录
空项目传送门:
上篇文章 定时器A中断 传送门:
本篇文章实践项目传送门:
基础知识:
MSP432定时器A对应引脚图:
定时器输出PWM相关库函数:
定时器输出PWM一般步骤:
1.配置GPIO复用:
2.配置结构体:
对于PWM的频率占空比的计算,我们可以通过以下公式进行计算:
3.初始化定时器:
尝试驱动舵机:
以下是我的9g舵机,以及驱动原理:
以下为舵机控制有关的源码:
以下为成功下载测试视频:
空项目传送门:
https://download.csdn.net/download/qq_64257614/87781382?spm=1001.2014.3001.5503
上篇文章 定时器A中断 传送门:
MSP432学习笔记7:定时器A中断_NULL指向我的博客-CSDN博客
本篇文章实践项目传送门:
https://download.csdn.net/download/qq_64257614/87825804?spm=1001.2014.3001.5503
基础知识:
之前在学习定时器A中断时,我们知道它有三种计数模式:
但在学习PWM输出时,我们只需关心 一和三 这俩种计数模式即可。
定时器A有七种输出模式,但常用的也就模式2与模式6:
我们可以发现模式2与模式6这俩个模式是互补的:
这是增计数模式下的输出:
这是增减计数模式下的输出:
当同时使能主通道和互补通道,就可以输出互补对称波形
这样俩种输出模式配合后,能生成带死区的互补PWM:
评估板一共有四个定时器A :TA0 TA1 TA2 TA3
每个定时器都有五个通道: CCR0 CCR1 CCR2 CCR3 CCR4
MSP432定时器A对应引脚图:
定时器输出PWM相关库函数:
以下库函数封装在 timer_a.h 文件中:
1.初始化定时器为PWM模式:
参数填选择的定时器以及配好的结构体地址
Timer_A_generatePWM(TIMER_Ax_BASE,&TimAx_PWMConfig);
2.改变比较值(占空比/周期):
通过改变CCR来改变定时器周期(与定时器中断通用)
Timer_A_setCompareValue(TIMER_Ax,COMPARE_REGISTER_x,CCR);
定时器输出PWM一般步骤:
0.配置时钟
1.配置GPIO复用
2.配置结构体
3.初始化定时器
1.配置GPIO复用:
我还是比较喜欢将初始化的过程都封装在一个初始化函数
进行统一分类编写:
先定义一个函数,在逐步添加初始化语句:
此处初始化的是PA1.1 就是P7.7脚。
//1.配置GPIO复用GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P7,GPIO_PIN7,GPIO_PRIMARY_MODULE_FUNCTION);
2.配置结构体:
此结构体定义在 Timer_a.h文件中
复制该结构体中的参数:
粘贴在刚才的初始化函数那:
修改语句,配置结构体参数:
//2.配置结构体
Timer_A_PWMConfig TimA1_PWMConfig;
TimA1_PWMConfig.clockSource=TIMER_A_CLOCKSOURCE_SMCLK;
TimA1_PWMConfig.clockSourceDivider=48;
TimA1_PWMConfig.timerPeriod=19999;
TimA1_PWMConfig.compareRegister=TIMER_A_CAPTURECOMPARE_REGISTER_1;
TimA1_PWMConfig.compareOutputMode=TIMER_A_OUTPUTMODE_TOGGLE_SET;
TimA1_PWMConfig.dutyCycle=9999;
以上结构体配置产生的是50Hz的方波, 就是0.05s/次
对于PWM的频率占空比的计算,我们可以通过以下公式进行计算:
- PWM频率 = 时钟源频率 / (时钟源除数值“时钟分频” * (CCR0值“自动重载值” + 1))
单位: Hz
PWM=48000000/(48*(19999+1))=50Hz
- 占空比 = (CCR1值 / CCR0值) * 100%
其中CCR0值是计数器最大计数值,
CCR1值是计数器计数到某个值时,输出PWM的占空比的相对值。
例如,如果要设置PWM频率为10kHz,时钟源频率为48MHz,时钟除数值为8,则CCR0值为4800。如果要设置占空比为50%,则CCR1值为2400。
此处方波为 50%占空比,所以计算公式为:
CCR1 占空比=(CCR0值“自动重载值” + 1 ) / 2 - 1 =9999
3.初始化定时器:
填上定时器A1,以及配置好的结构体地址:
//初始化定时器:
Timer_A_generatePWM(TIMER_A1_BASE,&TimA1_PWMConfig);
尝试驱动舵机:
以上配置完结后,下载程序我们就能尝试驱动舵机了:
此云台俩个舵机规格相同,此处我只配置驱动一个舵机了,
以下是我的9g舵机,以及驱动原理:
注:不同品牌舵机驱动原理不同,需要不同电压和信号频率
使用舵机不要超载、超速,以免损坏舵机
以下为商家给的说明:
舵机的控制一般需要一个20ms左右的时基脉冲,
该脉冲的高电平部分一般为0.5ms-2.5ms
范围内的角度控制脉冲部分,
总间隔为2ms。
以180度角度伺服为例,
那么对应的控制关系是这样的:
0.5ms--------------0度;
1.0ms------------45度;
1.5ms------------90度;
2.0ms-----------135度;
2.5ms-----------180度
我们将其转换为占空比,那就是:
2.5% 占空比———— 0度
5% 占空比———— 45度
7.5% 占空比———— 90度
10% 占空比———— 135度
12.5% 占空比———— 180度
该信号以方波形式发出。
总长20ms(0.02s)其实就是表示 频率为 50Hz
因此,我们只需在上面配置好的函数那 调整好 占空比即可!
以下为舵机控制有关的源码:
#include "sysinit.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
#include "tim32.h"
#include "delay.h"
#define CLKDIV 48
#define CCR0 19999
#define CCR1_MIN 500
#define CCR1_MAX 2500
void TimerA0_PWM_inint(void);
int main(void)
{
bool dir=1;
uint16_t i;
SysInit(); // 第3讲 时钟配置
uart_init(115200); // 第7讲 串口配置
delay_init(); // 第4讲 滴答延时
TimerA0_PWM_inint();
printf("Hello,MSP432!\r\n");
MAP_Interrupt_enableMaster(); // 开启总中断
while (1)
{
delay_ms(500);
if(dir) i+=500;
else i-=500;
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);
}
}
我们可以看到,全局变量#define了俩个变量:
#define CCR1_MIN 500
#define CCR1_MAX 2500
分别对应 0度 和 180度 的 占空比下,CCR1的值
该转换分度为 500,每加500,占空比加 2.5%,
这个小学数学自己算,我不教大家了哈~~~~~~~~
bool dir就是判断有没有到最大最小边界的,
然后每次加减都要有个500MS延时等待,以保证舵机确实转过这么多角度了。
里面最重要的还是改变比较值(占空比/周期)函数:
MAP_Timer_A_setCompareValue(TIMER_A1_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_1,i);
以下为成功下载测试视频:
MSP432P401r驱动舵机视频