一、pwm的概述
1.pwm的工作原理
图中,假定定时器工作在向上计数
PWM
模式,且当
CNT<CCRx
时,输出
0
,当
CNT>=CCRx
时输出
1
。那么就可以得到如上的
PWM
示意图:当
CNT
值小于
CCRx
的时候,
IO
输出低电平
(0)
,当
CNT
值大于等于
CCRx
的
时候,
IO
输出高电平
(1)
,当
CNT
达到
ARR
值的时候,重新归零,然后重新向上计数,依次
循环。改变
CCRx
的值,就可以改变
PWM
输出的占空比,改变
ARR
的值,就可以改变
PWM
输出的频率,这就是
PWM
输出的原理。
2.工作过程(以通道1为例)
CCR1:捕获比较(值)寄存器(X=1,2,3,4):设置比较值。
CCMR1: OC1M[2:0]位:
对于PWM方式下,用于设置PWM模式1【110】 或者PWM模式2【111】
CCER:CC1P位:输入/捕获1输出极性。0:高电平有效,1:低电平有效。
CCER:CC1E位:输入捕获1输出使能。0:关闭,1:打开。
二、寄存器的介绍
1.捕获/比较模式寄存器(TIMx_CCMR1/2)
该寄存器总共有
2
个,
TIMx _CCMR1 和 TIMx _CCMR2
。
TIMx_CCMR1
控制
CH1
和
2
,而
TIMx_CCMR2
控制
CH3
和
4
。该寄存器 的各位描述如图
所示:
2.捕获/比较使能寄存器(TIMx_CCER)
该寄存器控制着各个输入输出通道的开关。
该寄存器比较简单,我们这里只用到了
CC1E
位,该位是输入
/
捕获
1
输出使能位,要想
PWM
从
IO
口输出,这个位必须设置为
1
,所以我们需要设置该位为
1
。
3.捕获/比较寄存器(TIMx_CCR1~4)
该寄存器总共有
4
个,对应
4
个输通道 CH1~4
。
在输出模式下,该寄存器的值与 CNT
的值比较,根据比较结果产生相应动作。利用这点,
我们通过修改这个寄存器的值,就可以控制
PWM
的输出脉宽了。
三、函数的配置步骤
1.开启 TIM1 时钟,配置 PA8 为复用输出。
要使用
TIM1
,必须先开启
TIM1
的时钟。
这里还要配置
PA8
为复用输出(当然还要时能
PORTA
的时钟),这是因为
TIM1_CH1
通
道将使用
PA8
的复用功能作为输出。库函数使能
TIM3
时钟的方法是:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器 3 时钟
设置
PA8
为复用功能输出的方法
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
2.设置 TIM1 的 ARR 和 PSC。
在开启了
TIM1
的时钟之后,要设置
ARR
和
PSC
两个寄存器的值来控制输出
PWM
的
周期。当
PWM
周期太慢(低于
50Hz
)的时候,就会明显感觉到闪烁了。因此,
PWM
周
期在这里不宜设置的太小。这在库函数是通过
TIM_TimeBaseInit
函数实现的,调用的格式为:
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_OCInitStruct)
;
这种初始化格式大家学到这里应该也熟悉了,所以直接来看看结构体
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); //初始化 TIM1 OC1
4.使能 TIM1。
在完成以上设置了之后,需要使能
TIM1
。使能
TIM1
的方法:
TIM_Cmd(TIM1, ENABLE); //使能 TIM1
5.设置 MOE 输出,使能 PWM 输出。
普通定时器在完成以上设置了之后,就可以输出
PWM
了,但是高级定时器,还需要
使能刹车和死区寄存器(
TIM1_BDTR
)的
MOE
位,以使能整个
OCx
(即
PWM
)输出。库函
数的设置函数为:
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)
。
以上皆是对 正点原子stm32单片机的复习笔记 如有侵权立刻删