上一章,我们介绍了
STM32F429
的通用定时器
TIM3
,用该定时器的中断来控制
DS1
的闪烁,这一章,我们将向大家介绍如何使用
STM32F429
的
TIM3
来产生
PWM
输出。在本章中,我们将使用
TIM3
的通道 4 来产生
PWM
来控制
DS0
的亮度。
一、PWM 简介
脉冲宽度调制(PWM
),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽度的控制,PWM 原理如图所示:
上图就是一个简单的 PWM
原理示意图。图中,我们假定定时器工作在向上计数 PWM
模式,且当CNT<CCRx
时,输出 0,当 CNT>=CCRx
时输出 1。那么就可以得到如上的 PWM
示意图:当 CNT
值小于 CCRx
的时候,IO
输出低电平(0),当 CNT
值大于等于 CCRx
的时候,IO
输出高电平(1),当 CNT
达到 ARR
值的时候,重新归零,然后重新向上计数,依次循环。改变 CCRx
的值,就可以改变 PWM
输出的占空比,改变 ARR
的值,就可以改变 PWM
输出的频率,这就是 PWM
输出的原理。
STM32F429
的定时器除了 TIM6
和 7
。其他的定时器都可以用来产生 PWM
输出。其中高级定时器 TIM1
和 TIM8
可以同时产生多达 7 路的 PWM
输出。而通用定时器也能同时产生多达 4 路的 PWM
输出!这里我们仅使用 TIM3
的 CH4
产生一路 PWM
输出。
要使 STM32F429
的通用定时器 TIMx
产生 PWM
输出,除了上一章介绍的寄存器外,我们还会用到 3 个寄存器来控制 PWM
的。这三个寄存器分别是:捕获/比较模式寄存器(TIMx_CCMR1/2
)、捕获/比较使能寄存器(TIMx_CCER
)、捕获/比较寄存器(TIMx_CCR1~4
)。接下来我们简单介绍一下这三个寄存器。
-
捕获/比较模式寄存器:
TIMx_CCMR1/2
该寄存器一般有 2 个:TIMx _CCMR1
和TIMx _CCMR2
。TIMx_CCMR1
控制CH1
和2
,而TIMx_CCMR2
控制CH3
和4
。以TIM3
为例,TIM3_CCMR2
寄存器各位描述如图所示:
该寄存器的有些位在不同模式下,功能不一样,所以在图中,把寄存器分了 2 层,上面一层对应输出而下面的则对应输入。关于该寄存器的详细说明,请参考《STM32F4xx中文参考手册》第 435 页。这里我们需要说明的是模式设置位OC4M
,此部分由 3 位组成。总共可以配置成 7 种模式,我们使用的是PWM
模式,所以这 3 位必须设置为110/111
。这两种PWM
模式的区别就是输出电平的极性相反。另外CC4S
用于设置通道的方向(输入/输出)默认设置为 0,就是设置通道作为输出使用。 -
捕获/比较使能寄存器:
TIMx_CCER
该寄存器控制着各个输入输出通道的开关。该寄存器的各位描述如图所示:
该寄存器比较简单,我们这里只用到了CC4E
位,该位是输入/捕获 4 输出使能位,要想PWM
从IO
口输出,这个位必须设置为 1,所以我们需要设置该位为 1。该寄存器更详细的介绍了,请参考《STM32F4xx 中文参考手册》第 436 页。 -
捕获/比较寄存器:
TIMx_CCR1~4
该寄存器总共有 4 个,对应 4 个通道CH1~4
。我们使用的是通道 4,TIM3_CCR4
寄存器的各位描述如图所示:
在输出模式下,该寄存器的值与CNT
的值比较,根据比较结果产生相应动作。利用这点,我们通过修改这个寄存器的值,就可以控制PWM
的输出脉宽了。如果是通用定时器,则配置以上三个寄存器就够了,但是如果是高级定时器,则还需要配置:刹车和死区寄存器(TIMx_BDTR
),该寄存器各位描述如图所示:
该寄存器,我们只需要关注最高位:MOE
位,要想高级定时器的PWM
正常输出,则必须设置MOE
位为 1,否则不会有输出。注意:通用定时器不需要配置这个。该寄存器更详细的介绍请参考《STM32F4xx 中文参考手册》第 386 页。
本章,我们使用的是 TIM3
的通道 4,所以我们需要修改 TIM3_CCR4
以实现脉宽控制 DS0
的亮度。
下面介绍通过 HAL
库来配置该功能的步骤,相关的函数设置在库函数文件 stm32f4xx_tim.h
和stm32f4xx_tim.c
文件中。
-
开启
TIM3
和GPIO
时钟,配置PB1
选择复用功能AF1
(TIM3
)输出
要使用TIM3
,我们必须先开启TIM3
的时钟。HAL
库使能TIM3
时钟和GPIO
时钟方法是:__HAL_RCC_TIM3_CLK_ENABLE(); //使能定时器 3 __HAL_RCC_GPIOB_CLK_ENABLE(); //开启 GPIOB 时钟
配置
PB1
为复用(AF1
)输出,才可以实现TIM3_CH4
的PWM
经过PB1
输出。接下来便是要配置PB1
复用映射为TIM3
的PWM
输出引脚。关于IO
口复用映射,在串口通信实验中有详细讲解,主要是通过函数HAL_GPIO_Init
来实现的:GPIO_InitTypeDef GPIO_Initure; GPIO_Initure.Pin=GPIO_PIN_1; //PB1 GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出 GPIO_Initure.Pull=GPIO_PULLUP; //上拉 GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速 GPIO_Initure.Alternate= GPIO_AF2_TIM3; //PB1 复用为 TIM3_CH4 HAL_GPIO_Init(GPIOB,&GPIO_Initure);
在
IO
口初始化配置中,我