这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界» 论坛首页» 嵌入式开发» STM32» STM32学习--PWM

共1条 1/1 1 跳转至

STM32学习--PWM

高工
2022-02-14 10:52:57 打赏

概述


PWM(脉冲宽度调制):利用微处理器的数字输出来对模拟电路进行控制,即对脉冲宽度的控制

1644807066475159.png


假定定时器工作在向上计数

PWM 模式,且当 CNT=CCRx 时输出 1。那么就可以得到如上的图

PWM 示意图:当 CNT 值小于 CCRx 的时候,IO 输出低电平(0),当 CNT 值大于等于 CCRx 的

时候,IO 输出高电平(1),当 CNT 达到 ARR 值的时候,重新归零,然后重新向上计数,依次

循环。改变 CCRx 的值,就可以改变 PWM 输出的占空比,改变 ARR 的值,就可以改变 PWM

输出的频率,这就是 PWM 输出的原理。

CNT(16位自动装载计数器)

ARR(自动重装载寄存器):900,不分频=80Khz


如现在在点亮LED,低电平点亮。当CCRx的值很小的时候,PWM大部分都是输出1,LED亮度很低。当CCRx的值开始变大的时候,PWM输出0的时间就长了,LED亮度就开始变高。(当CCRx的值达到ARR的1/3的时候亮度就很高了,基本上看不到LED亮度变化)


TM32 的定时器除了 TIM6 和 7。其他的定时器都可以用来产生 PWM 输出。其中高级定

时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出。而通用定时器也能同时产生多达 4

路的 PWM 输出,这样,STM32 最多可以同时产生 30 路 PWM 输出!


寄存器


除了定时器需要的寄存器外还需要4个寄存器(高级4个,普通定时器需要3个):捕获/比较模式寄存器(TIMx_CCMR1/2)、捕获/比较使能寄存器(TIMx_CCER)、捕获/比较寄存器(TIMx_CCR1~4)以及刹车和死区寄存器(TIMx_BDTR)。

1)捕获/比较模式寄存器(TIMx_CCMR1/2),该寄存器总共有 2 个,TIMx _CCMR1和 TIMx _CCMR2。TIMx_CCMR1 控制 CH1 和 2,而 TIMx_CCMR2 控制 CH3 和 4。

image.png

上面一层对应输出时的设置,下面对应输入。模式设置位OCxM,此播放由3位组成,可配置7种模式。使用PWM模式,必须设置位110/111。这两种模式的输出电平极性相反。CCxS用来设置通道的方向(输入、输出),默认为0输出


PWM模式1- 在向上计数时,一旦TIMx_CNTTIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。 111:PWM模式2- 在向上计数时,一旦TIMx_CNTTIMx_CCR1时通道1为有效电平,否则为无效电平。


向上计数时,模式2高电平等效模式1低电平


2)捕获/比较使能寄存器(TIMx_CCER),控制输入输出通道的开关。

image.png

CCIE位:输入/捕获1输出使能位。PWM从IO口输出,这个位必须为1.


3)捕获/比较寄存器(TIMx_CCR1~4):有4个,对应4个通道CH1-4.


image.png

在输出模式下,该寄存器的值与 CNT 的值比较,根据比较结果产生相应动作。利用这点,

我们通过修改这个寄存器的值,就可以控制 PWM 的输出脉宽了


通用寄存器以上三个就够了,高级寄存器还需要配置:刹车和死区寄存器(TIMx_BDTR)

4)刹车和死区寄存器(TIMx_BDTR)

image.png

MOE为:高级定时器PWM正常输出必须设置位1


具体步骤

1)开启 TIM1 时钟,配置 PA8 为复用输出。

TIM1_CH1通道使用PA8的复用功能输出,需要配置PA8位复用输出


RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器 3 时钟

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出


2)设置TIM1的ARR和PSC控制输出 PWM 的周期。(STM32学习–定时器)


3)设置TIM1_CH1的PWM模式和通道方向,使能TIM1的CH1输出

这里先要设置 TIM1_CH1 为 PWM 模式(默认是冻结的),PWM通道设置通过TIM_OC1Init()-TIM_OC4Init()设置


void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);

typedef struct

{

uint16_t TIM_OCMode; //设置PWM还是输出比较

uint16_t TIM_OutputState; //设置比较输出使能,也就是使能 PWM 输出到端口

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_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_OCInitStructure.TIM_Pulse = 0;

TIM_OC1Init(TIM1, &TIM_OCInitStructure); //初始化 TIM1 OC1


4)使能TIM1


TIM_Cmd(TIM1,ENABLE)


5)设置MOE输出,使能PWM输出(高级定时器)


TIM_CtrlPWMOutputs(TIM1,ENABLE)


6)修改TIM1_CCR1控制占空比


void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1)//可以控制LED亮度根据Compare1的值。


其实是将Compare1的值写入TIMx->CCR1。


7)补充


TIM_ARRPreloadConfig(TIM1, ENABLE); //使能 TIMx 在 ARR 上的预装载寄存器

TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //CH1预装载使能

TIM_Cmd(TIM1, ENABLE); //④使能 TIM1





关键词: STM32 PWM

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册]