1.简介:
什么是PWM
脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。
PWM工作原理
SMT32F1系列共有8个定时器:
高级定时器(TIM1、TIM8);通用定时器(TIM2、TIM3、TIM4、TIM5);基本定时器(TIM6、TIM7)。
SMT32F4系列共有15个定时器:
高级定时器(TIM1、TIM8);通用定时器(TIM2、TIM3、TIM4、TIM5、TIM9~TIM14);基本定时器(TIM6、TIM7)。
STM32的每个通用定时器都有独立的4个通道可以用来作为:输入捕获、输出比较、PWM输出、单脉冲模式输出等。
STM32的定时器除了TIM6和TIM7(基本定时器)之外,其他的定时器都可以产生PWM输出。其中,高级定时器TIM1、TIM8可以同时产生7路PWM输出
原理讲解:
下图为向上计数模式:
- 在PWM输出模式下,除了CNT(计数器当前值)、ARR(自动重装载值)之外,还多了一个值CCRx(捕获/比较寄存器值)。
- 当CNT小于CCRx时,TIMx_CHx通道输出低电平;
- 当CNT等于或大于CCRx时,TIMx_CHx通道输出高电平。
PWM的一个周期
- 定时器从0开始向上计数
- 当0-t1段,定时器计数器TIMx_CNT值小于CCRx值,输出低电平
- t1-t2段,定时器计数器TIMx_CNT值大于CCRx值,输出高电平
- 当TIMx_CNT值达到ARR时,定时器溢出,重新向上计数...循环此过程
- 至此一个PWM周期完成
总结:
每个定时器有四个通道,每一个通道都有一个捕获比较寄存器,
将寄存器值和计数器值比较,通过比较结果输出高低电平,便可以实现脉冲宽度调制模式(PWM信号)
TIMx_ARR寄存器确定PWM频率,
TIMx_CCRx寄存器确定占空比
详解:
若配置脉冲计数器TIMx_CNT为向上计数,而重载寄存器TIMx_ARR配置为N,即TIMx_CNT的当前计数值数值X在TIMxCLK时钟源的驱动下不断累加,当TIMx_CNT的数值X大于N时,会重置TIMx_CNT数值为0重新计数。
而在TIMxCNT计数的同时,TIMxCNT的计数值X会与比较寄存器TIMx_CCR预先存储了的数值A进行比较,当脉冲计数器TIMx_CNT的数值X小于比较寄存器TIMx_CCR的值A时,输出高电平(或低电平),相反地,当脉冲计数器的数值X大于或等于比较寄存器的值A时,输出低电平(或高电平)。
如此循环,得到的输出脉冲周期就为重载寄存器TIMx_ARR存储的数值(N+1)乘以触发脉冲的时钟周期,其脉冲宽度则为比较寄存器TIMx_CCR的值A乘以触发脉冲的时钟周期,即输出PWM的占空比为A/(N+1)。
PWM的工作模式:
- PWM模式1(向上计数) :计数器从0计数加到自动重装载值(TIMx_ARR),然后重新从0开始计数,并且产生一个计数器溢出事件
- PWM模式2(向下计数) :计数器从自动重装载值(TIMx_ARR)减到0,然后重新从重装载值(TIMx_ARR)开始递减,并且产生一个计数器溢出事件
设置寄存器TIMx_CCMR1的OC1M[2:0]位来确定PWM的输出模式:
- PWM模式1:在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为有效电平,否则为无效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。
- PWM模式2:在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为无效电平,否则为有效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为有效电平,否则为无效电平。
PWM模式1和模式2中都是通过比较CNT和CCR1寄存器,来决定有效电平,这里的有效电平不确定是高电平还是低电平。那么如何确实电平状态呢?通过CCER寄存器的位1标志位来进行确定(OC1),0高电平有效,1低电平有效,这样就可以对应PWM模式来判断输出脉冲了
例如:PWM1模式下,CNT<CCR1时是有效电平,在CCER寄存器位1写入’1‘,那么OC1通道产生的脉冲首先是低电平,然后是高电平;反之,若在CCER寄存器位1写入'0',那么OC1通道产生的脉冲首先是高电平,然后是低电平。
PWM的工作过程
1、CCR1寄存器:捕获/比较值寄存器:设置比较值;
计数器值TIMx_CNT与通道1捕获比较寄存器CCR1进行比较,通过比较结果输出有效电平和无效电平
- OC1REF=0 有效电平
- OC1REF=1 无效电平
2、TIMx_CCMR1寄存器:OC1M[2:0]位:用于设置PWM模式
110:PWM模式1
111:PWM模式2
3、CCER寄存器:CC1P位:输入/捕获1输出极性。
0:高电平为有效电平
1:低电平为有效电平
4、CCER寄存器:CC1E位:输入/捕获1输出使能。
0:关闭使能
1:打开使能
5、输出电平信号
6.定时器输出通道引脚
2.工程创建:
1设置RCC
设置高速外部时钟HSE 选择外部时钟源
2.时钟设置
3.设置定时器
- 1.选择TIM3
- 2.设置定时器时钟源为内部时钟源
- 设置定时器CH2为PWM模式
- 3.对应管脚自动设置为复用模式
- 4.可自行选择是否开启定时器中断
设置Channel1~4 就是设置4个定时器通道功能 (输入捕获、输出比较、PWM输出、单脉冲模式)
- Mode 选择PWM模式1
- Pulse(占空比值) 先给0
- Fast Mode PWM脉冲快速模式 : 和我们配置无关,不使能
- PWM 极性: 设置为低电平 PS: 由于LED是低电平点亮,所以我们把极性设置为low
在这里,我们设置预分频系数(PSC)为71,计数周期(自动加载值)为499,则定时器的溢出频率(也可以说是PWM的周期),就是72MHZ(Tclk)/(71+1) *(499+1)=2KHZ.占空比我们这里设置了CRR为0,则一开始占空比为0.
PWM频率:
Fpwm =Tclk / ((arr+1)*(psc+1))(单位:Hz)
- arr 是计数器值
- psc 是预分频值
占空比:
- duty circle = TIM3->CCR1 / arr(单位:%)
- TIM3->CCR1 用户设定值
比如 定时器频率Tclk = 72Mhz arr=499 psc=71 那么PWM频率就是720000/500/72= 2000Hz,即2KHz
arr=499,TIM3->CCR1=250 则pwm的占空比为50%
改CCR1可以修改占空比,修改arr可以修改频率
4.工程创建和项目文件设置
然后就可以创建了
3,函数讲解:
和上一章一样,我们首先要使能一下PWM Channel2
/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);
/* USER CODE END 2 */
由于我们要实现呼吸灯效果,故我们需要不断改变我们的占空比
首先定义下变量:
/* USER CODE BEGIN 1 */
uint16_t pwmVal=0; //PWM占空比
/* USER CODE END 1 */
在while循环中添加代码:、
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
while (pwmVal< 500)
{
pwmVal++;
__HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_2, pwmVal); //修改比较值,修改占空比
// TIM3->CCR1 = pwmVal; 与上方相同
HAL_Delay(1);
}
while (pwmVal)
{
pwmVal--;
__HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_2, pwmVal); //修改比较值,修改占空比
// TIM3->CCR1 = pwmVal; 与上方相同
HAL_Delay(1);
}
HAL_Delay(200);
/* USER CODE END 3 */
}