脉冲宽度调制(PWM),是英文“ Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽度的控制。
STM32 的定时器除了 TIM6 和7。其他的定时器都可以用来产生PWM 输出。其中高级定
时器TIM1 和 TIM8 可以同时产生多达 7 路的 PWM输出。而通用定时器也能同时产生多达4路的PWM 输出,这样, STM32 最多可以同时产生 30路 PWM 输出!这里我们仅使用 TIM1的CH1 产生一路 PWM 输出。要使STM32 的高级定时器 TIM1 产生 PWM 输出,除了上一章介绍的几个寄存器( ARR、PSC、CR1 等) 外,我们还会用到 4 个寄存器(通用定时器则只要 3 个),来控制 PWM 的输出。这四个寄存器分别是[size=+0]:[size=+0]捕获/比较模式寄存器(TIMx_CCMR1/2)、捕获/比较使能寄存器(TIMx_CCER)、捕获/比较寄存器( TIMx_CCR1~4) 以及刹车和死区寄存器(TIMx_BDTR)。
接下来我们简单介绍一下这四个寄存器。
首先是捕获/比较模式寄存器(TIMx_CCMR1/2),该寄存器总共有 2 个, TIMx _CCMR1和TIMx _CCMR2。 TIMx_CCMR1 控制 CH1 和 2,而 TIMx_CCMR2 控制 CH3 和4这里我们需要说明的是模式设置位OCxM,此部分由3 位组成。总共可以配置成 7种模式,我们使用的是 PWM 模式,这 3 位必须设置为110/111。这两种PWM 模式的区别就是输出电平的极性相反。 另外 CCxS 用于设置通道的方向(输入/输出)默认设置为0,就是设置通道作为输出使用。
接下来,我们介绍捕获/比较使能寄存器(TIMx_CCER),该寄存器控制着各个输入输出通道的开关。该寄存器的各位描述如图13.1.2 所示:
图 13.1.2 TIMx_ CCER寄存器各位描述该寄存器比较简单,我们这里只用到了CC1E 位,该位是输入/捕获 1 输出使能位,要想PWM从 IO 口输出,这个位必须设置为 1,所以我们需要设置该位为 1。该寄存器更详细的介绍了,请参考《STM32 参考手册》第 250 页, 最后,我们介绍一下捕获/比较寄存器(TIMx_CCR1~4),该寄存器总共有 4 个,对应 4 个输通道CH1~4。因为这 4 个寄存器都差不多,我们仅以 TIMx_CCR1 为例介绍,该寄存器的各
注意:如果只是普通定时器,只需要配置三个寄存器
捕获/比较模式寄存器(TIMx_CCMR1/2)、捕获/比较使能寄存器(TIMx_CCER)、捕获/比较寄存器(TIMx_CCR1~4)。
对于高级定时器1,8还需要配置刹车和死区寄存器(TIMx_BDTR)。对于高级定时器我们只需要关注MOE:主输出使能,必须置1,否则不能够输出。
TIM1 单路PWM的配置 1.开启TIM1定时器时钟,配置PA8为复用输出(说明PA8不再是简单的IO口,而是做定时器用了,注意IO输出最大为50MHZ)有一点要注意,定时器的时钟不是直接来自APB1或APB2,而是来自于输入为APB1或APB2的一个倍频器,当APB1的预分频系数为1时,这个倍频器不起作用,定时器的时钟频率等于APB1的频率;当 APB1的预分频系数为其它数值(即预分频系数为2、4、8或16)时,这个倍频器起作用,定时器的时钟频率等于APB1的频率两倍。 库函数使能TIM3的方法: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); PA8的复用功能配置 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
2.在开启了TIM1时钟后就需要设置ARR,PSC,通过设置这两个值来控制PWM的周期 具体配置如下 TIM_TimeBaseStructure.TIM_Period = arr; //设置自动重装载值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS =Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx 的
3)设置 TIM1_CH1 的 PWM 模式及通道方向,使能 TIM1 的 CH1 输出。
接下来,我们要设置 TIM1_CH1 为 PWM 模式(默认是冻结的),因为我们的 DS0 是低电
平亮,而我们希望当 CCR1 的值小的时候, DS0 就暗, CCR1 值大的时候, DS0 就亮,所以我
们要通过配置 TIM1_CCMR1 的相关位来控制 TIM1_CH1 的模式。在库函数中, PWM 通道设
置是通过函数 TIM_OC1Init()~TIM_OC4Init()来设置的,不同的通道的设置函数不一样,这里我
们使用的是通道 1,所以使用的函数是TIM_OC1Init()。 void TIM——OC1Init(TIM_TypeDef*TIMx,TIM_OCInitTypeDef*TIM_OCInitStructure)
这种初始化格式大家学到这里应该也熟悉了,所以我们直接来看看结构体 TIM_OCInitTypeDef
的定义:
typedef struct
{
uint16_t TIM_OCMode;
uint16_t TIM_OutputState;
uint16_t TIM_OutputNState; */
uint16_t TIM_Pulse;
uint16_t TIM_OCPolarity;
uint16_t TIM_OCNPolarity;
uint16_t TIM_OCIdleState;
uint16_t TIM_OCNIdleState;
}TIM_OCInitTypeDef;
参数 TIM_OCMode 设置模式是 PWM 还是输出比较,这里我们是 PWM 模式。
参数 TIM_OutputState 用来设置比较输出使能,也就是使能 PWM 输出到端口。
参数 TIM_OCPolarity 用来设置极性是高还是低。
其他的参数 TIM_OutputNState, TIM_OCNPolarity, TIM_OCIdleState 和TIM_OCNIdleState 是
高级定时器 TIM1 和 TIM8 才用到的。
要实现我们上面提到的场景,方法是:
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择 PWM 模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//输出极性高
TIM_OC1Init(TIM1, &TIM_OCInitStructure); //初始化 TIM1OC1
4)使能 TIM1。
在完成以上设置了之后,我们需要使能 TIM1。使能 TIM1 的方法前面已经讲解过:
TIM_Cmd(TIM1, ENABLE); //使能 TIM1
5)设置 MOE 输出,使能 PWM 输出。
普通定时器在完成以上设置了之后,就可以输出 PWM 了,但是高级定时器,我们还需要
使能刹车和死区寄存器(TIM1_BDTR)的 MOE 位,以使能整个 OCx(即 PWM)输出。 库函
数的设置函数为:【这个配置只用于定时器1与定时器8两个高级定时器,一般的定时不要配置这两个】
TIM_CtrlPWMOutputs(TIM1,ENABLE);//MOE 主输出使能
6)修改 TIM1_CCR1 来控制占空比。
最后,在经过以上设置之后, PWM 其实已经开始输出了,只是其占空比和频率都是固定
的,而我们通过修改 TIM1_CCR1 则可以控制 CH1 的输出占空比。继而控制 DS0 的亮度。
在库函数中,修改 TIM1_CCR1 占空比的函数是:
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
理所当然,对于其他通道,分别有一个函数名字,函数格式为TIM_SetComparex(x=1,2,3,4);
PWM占空比,周期计算
下面的这个是stm32的定时器逻辑图,上来有助于理解:
TIM3的ARR寄存器和PSC寄存器, 确定PWM频率。
这里配置的这两个定时器确定了PWM的频率,我的理解是:PWM的周期(频率)就是ARR寄存器值与PSC寄存器值相乘得来,但不是简单意义上的相乘,例如要设置PWM的频率参考上次通用定时器中设置溢出时间的算法,例如输出100HZ频率的PWM,首先,确定TIMx的时钟,除非APB1的时钟分频数设置为1,否则通用定时器TIMx的时钟是APB1时钟的2倍,这时的TIMx时钟为72MHz,用这个TIMx时钟72MHz除以(PSC+1),得到定时器每隔多少秒涨一次,这里给PSC赋7199,计算得定时器每隔0.0001秒涨一次,即此时频率为10KHz,再把这个值乘以(ARR+1)得出PWM频率,假如ARR值为0,即0.0001*(0+1),则输出PWM频率为10KHz,再假如输出频率为100Hz的PWM,则将ARR寄存器设置为99即可。如果想调整PWM占空比精度,则只需降低PSC寄存器的值即可。 TIMx_CCRx寄存器,
确定PWM的占空比。
TIMx_CCR1—TIMx_CCR4确定定时器的CH1—CH4四路PWM的占空比。直接给该寄存器赋0—65535值即可确定占空比。占空比计算方法:TIMx_CCRx的值除以ARR寄存器的值即为占空比,因为占空比在0—100%之间,所以一般TIMx_CCRx寄存器值不能超过ARR寄存器的值,否则可能会引起PWM的频率或占空比的准确性。
|