一、PWM工作过程
工作框图
2. 主要寄存器
a). TIMx_CCR1
捕获比较(值)寄存器(x=1,2,3,4):设置比较值。
b). TIMx_CNT
计数器值与捕获比较寄存器CCR1进行比较,通过比较结果输出有效电平和无效电平 OC1REF=0 无效电平,OC1REF=1 无效电平。
c). TIMx_CCMR1
OC1M[2:0]位:对于PWM方式下,用于设置PWM模式1(110)或者PWM模式2(111)。
110:对应STM32CubeMX中PWM模式1: 在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为有效电平,否则为无效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。
111:对应STM32CubeMX中PWM模式2: 在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为无效电平,否则为有效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为有效电平,否则为无效电平。
d). TIMx_CCER
CC1P位,输入/捕获1输出极性。0:高电平有效,1:低电平有效。
CC1E位,输入/捕获1输出使能。0:关闭,1:打开。
二、PWM的原理
由之前的定时器中断实验知道,定时器内部有一个记录定时器当前值的寄存器CNT(对应图中黑线)和一个记录定时器自动重装载值的寄存器ARR(对应图中橘线)。而在PWM工作模式下,我们依然利用这两个定时器来记录时间,不同的是多引入一个寄存器CCRx(对应图中红线),这个寄存器用于控制PWM输出波的有效电平长度(占空比);引入CCMRx寄存器来控制PWM模式(对应PWM是模式1还是2);引入寄存器CCERx:CC1P位控制输出电平极性。
假定定时器工作在向上计数 PWM模式,且当 CNT<CCRx 时,输出 0,当 CNT>=CCRx 时输出 1。当 CNT 达到 ARR 值的时候,重新归零,然后重新向上计数,依次循环。改变 CCRx 的值,就可以改变 PWM 输出的占空比,改变 ARR 的值,就可以改变 PWM 输出的频率。
链接:https://blog.csdn.net/wei348144881/article/details/109091539
STM32——PWM知识详解_stm32pwm_笛卡尔的叹息的博客-CSDN博客
三、使用PWM实现呼吸灯
初始化引脚、时钟
SystemClock_Config();
MX_GPIO_Init();
MX_TIM3_Init();
初始化定时器参数,包含自动重装值,分频系数,计数方式等
void MX_TIM3_Init(void)
{
htim3.Instance = TIM3;
htim3.Init.Prescaler = 720-1;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 500-1;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
}
开启定时器
HAL_TIM_Base_Start(&htim3);
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);
主函数
int i=0;
for(i=0;i<500;i++)
{
__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,i);
//改变占空比,逐渐提高低电平的持续时间
HAL_Delay(1);
}
for(i=500;i>0;i--)
{
__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,i); //改变占空比,逐渐降低低电平的持续时间
HAL_Delay(1);
}
解释
下面给出提升占空比的简易示意图,对应上面的第一个for循环,上面的for循环应该会产生500个这样的渐变。这样就能实现呼吸灯的效果。
此外还有亮度递减的过程,对应上面第二个for循环,图中未画出。