定时器主要由时钟控制、时基单元、输入捕获和输出比较等部分组成。
时钟控制包含触发控制器、从模式控制器和编码器接口等,可以选择内部时钟(CK_INT:默认值)、外部时钟模式1(TIxFPx)、外部时钟模式2(ETR)和内部触发(ITRx)。
时基单元包含16位计数器CNT、预分频器PSC、自动重装载寄存器ARR和重复次数计数器RCR。计数器可以向上计数、向下计数或向上向下双向计数,计数器时钟由预分频器对多种时钟源分频得到,计数器初值来自自动重装载寄存器,重复次数计数器实现重复计数。
输入捕获包含输入滤波器和边沿检测器、预分频器和捕获/比较寄存器等,可以捕获计数器的值到捕获/比较寄存器,也可以测量PWM信号的周期和脉冲宽度。
输出比较包含捕获/比较寄存器、死区发生器DTG和输出控制,可以输出单脉冲,也可以输出PWM信号。
首先说明如下图所示本工程在时钟树里配置的HCLK是80Mhz |
如果配置的不是80Mhz,下面计算过程中把80改成自己工程的HCLK值 |
实现功能:(一般题目中测量PWM波要求使用PA6或PA7引脚,通道可自行选择,以下通道选取做个参考即可)
TIM1通过CH1N(PA7)输出200Hz占空比10%的矩形波 |
TIM3通过CH1(PA6)输出100Hz占空比10%的矩形波 |
TIM3的CH1(PA6)
配置解读:
1.PWM频率: Fpwm =Tclk / ((arr+1)*(psc+1))(单位:Hz),arr 是计数器值,psc 是预分频值
如上图所示,预分频系数在Prescaler中设为79,频率被预先分频为80MHz/(79+1)=1Mhz
且我们选择的是向上计数模式,计数器CNT如下图,每次向上计数到ARR,计数器值arr在Counter Period中设为9999,即从0计数到9999,共10000。计数周期是10000,频率又被分为1Mhz/(9999+1)=100Hz。
并且由公式计算也可直接得PWM频率为80MHz/(79+1)/(9999+1)=100Hz
2.占空比: duty circle = TIM3->CCR1 / arr(单位:%)
PWM模式1:在向上计数时,一旦TIMx_CNT
PWM模式2:在向上计数时,一旦TIMx_CNT
我们选择的是PWM模式1,且高电平有效,即当CNT
在CubeMx中我们配置,CCR1的值在Pluse中设为1000,计数器值arr在Counter Period中设为9999。
那么占空比为1000/(9999+1)=10%
3.产生固定频率和固定占空比就在CubeMx中配置成自己想要的就可以了,如果程序中需要改变频率和占空比的话,在代码中修改CCR1可以修改占空比,修改arr可以修改频率。
TIM1的CH1N(PA7)
1.在main.c中用户添加代码区添加以下代码
//在main.c的初始化中调用
void TIM_Init(void)
{
HAL_TIM_PWM_Start(&htim1,2); /*启动TIM1_CHIN PWM*///因为是通道1的互补通道,所以这里写2
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);/* 启动TIM3_CH1 PWM */
}
2.最后在main.c初始化中调用TIM_Init()
实现PWM波输出代码部分非常简单。大家就可以用示波器观察以下PA6和PA7的频率和占空比是否正确了。
3.若想要根据条件改变PWM频率和占空比
使用下面两个函数
__HAL_TIM_SET_AUTORELOAD(htim, arr);//设置自动重装值
__HAL_TIM_SET_COMPARE(htim, Channel, cmp);//设置比较值
比如设置TIM3的CH1频率为100Hz,占空比为20%。
//在while里调用
void TIM_Proc(void)
{
__HAL_TIM_SET_AUTORELOAD(&htim3, 9999);
__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_1,2000);
}
最后在while中调用TIM_Proc();
如果想用开发板测量PWM波的频率和占空比,学习【蓝桥杯嵌入式组】HAL库STM32CubeMx学习笔记七:05-TIM(下)
在这里有一些学习资料建议,欢迎批评指正【蓝桥杯嵌入式组】HAL库STM32CubeMx学习笔记汇总:学习建议及资料