从大部分的视频首先教学的通用定时器讲起,以STM32G431RBT6为例,其通用定时器为TIM2/TIM3/TIM4/TIM5,都具备
- 输入捕获
- 输出比较
- PWM输出
- 单脉冲模式输出
以官方参考手册中的图来进行说明
输入捕获
输入捕获是指,TIM_CH1的电平经过滤波和边缘检测后,检测到上升沿,触发中断,控制后续电路,将CNT counter的值锁存到CCR寄存器中,即将CNT counter的值赋给CCR寄存器。
由此可见,输入捕获的捕获,其实是CCR寄存器捕获了CNT counter的值,但以输入的电平为特征。
所以输入捕获可以用来测量PWM的频率、占空比等的原因就是,每次PWM的上升沿被检测使得CCR寄存器内部存了持续递增的值(CNT counter),在下一次测得上升沿后,自然可以将这次捕获到的值与上次的值相减得出PWM频率、占空比等。
void 中断回调函数
{
static uint32_t Old = 0; //旧的CCR的值
static uint32_t New = 0; //新的CCR的值
static uint32_t PWM_Period = 0;//PWM频率
New = HAL_ReadCaptureValue(&htim2, TIM_CHANNEL_1);
if(New < Old)
PWM_Period = 100000 + New - Old; //十六进制不足会自动+特别大的数,需要特判
PWM_Period = New - Old; //可以接LCD显示该值
}
输出比较
输出比较,这个比较是把CNT counter的值和CCR寄存器(其实是CCR的影子寄存器,这个时候就不是输入捕获那样去捕获,而是你去赋一个值)的值作比较,当一方大于另一方的时候,就输出高/低电平(取决于你)。
那么输出比较怎么去控制输出PWM的频率、占空比呢?
答:改变CCR寄存器内部的值
__HAL_TIM_SetCompare(&htimx,TIM_CHANNEL_x,x)
- 第一个参数&htimx,是在cubemx里设置的TIMx
- 第二个参数是在端口设置的CHANNEL
- 第三个参数是CCR寄存器的值
主要调整的就是第三个参数,你可以
void 中断回调函数
{
static uint16_t CCR_Val = 0; //CCR的值
static int Dir = 0; //方向,递增/减
if(Dir){
CCR_Val += 5;
if(CCR_Val > 10000){
CCR_Val = 9999;
Dir = !Dir;
}
}
if(!Dir){
CCR_Val -= 5;
if(CCR_Val < 5000)
Dir = !Dir;
}
__HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_3, CCR_Val);
}
不难发现,在每次自动重装载时,偷偷地把CCR寄存器的值+/-5,就可以实现呼吸灯的效果,因为PWM的占空比以极小的周期递增/减,使LED的光强肉眼看起来逐渐变亮/暗。