stm32定时器输出PWM波的结构体
一、有哪些定时器能输出PWM波呢?
①stm32除了TIM6~TIM7(基本定时器)之外,其他都可以产生PWM波输出、
②通用寄存器:TIM2~TIM5,每个定时器都有四个独立通道可以作为:输入捕获、输出比较、PWM输出、单脉冲模式输出
③高级定时器TIM1、TIM8可以同时产生7路PWM输出;而通用定时器可以同时产生4路PWM输出,这样STM32最多同时输出30路P。WM输出
二、通用定时器输出PWM波工作原理:
主要有三个关键值: CNT(计数器当前值)、ARR(自定重装载值)、CCRx(捕获/比较寄存器值)
以向上计数为例讲解:
CNT与CCRx之间关系:
①当CNT小于CCRx时,TIMx_CHx通道输出低电平。
②当CNT等于或者大于CCRx时,TIMx_CHx通道输出高电平。
总结:
所谓的脉宽调制信号(PWM波),就是TIMx_ARR自定重装载寄存器确定频率(由它决定PWM周期),TIMx_CCRx寄存器确定占空比信号。
三、PWM内部的运行机制要关注的几个参数值:
①CCR1:设置捕获比较寄存器,设置比较值。
②CCMR1寄存器区: 设置PWM模式1或者PWM模式2
PWM模式1(边沿对齐模式):
向上计数时:当TIMx_CNT小于TIMx_CCRx时,TIMx_CHx通道1为有效电平,否则为无效电平。
向下计数时:当CNT大于CCRx时,TIMx_CHx通道1为有效电平,否则为无效电平。
PWM模式2(中央对齐):
向上计数时:当TIMx_CNT小于TIMx_CCRx时,TIMx_CHx通道1为无效电平,否则为无效电平。
向下计数时:当CNT大于CCRx时,TIMx_CHx通道1为有效电平,否则为无效电平。
③CCER:
P位:输出/捕获 :设置极性:0高电平有效,1低电平有效
E位:输出/捕获 :使能端口
四、定时器输出PWM波的结构体
typedef struct
{ //配置PWM模式一或者模式二
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;
主要配置以下几项:
① uint16_t TIM_OCMode : 配置PWM模式一或者模式二
② uint16_t TIM_OutputState : 配置比较输出使能
③uint16_t TIM_OCPolarity : 配置输出极性
五、定时器库函数的讲解
//初始化结构体
void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
//设置比较值函数
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
//使能输出比较预装载
void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
//使能自动重装载的预装载寄存器的允许位
void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
//配置修改极性
void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
六、配置定时器输出PWM波的步骤:
以TIM3为例输出PWM波:
TIM3为复用重影像PB5引脚(stm32中文手册8.2.7)
定时器3的通道2
①GPIO结构体
②配置通用定时器结构体
③配置定时去输出PWM波结构体(初始化、使能、初始化重装载值、选择GPIO部分映射)
④打开时钟:GPIO时钟、TIM定时时钟、部分重映射时钟
⑤配置PWM比较值
七、配置定时器输出PWM波的代码
void MotorG90_Init(void)
{
GPIO_InitTypeDef gpioPB5_Struct;
TIM_TimeBaseInitTypeDef tim3_Struct;
TIM_OCInitTypeDef motorG90_Struct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3 , ENABLE);
gpioPB5_Struct.GPIO_Mode = GPIO_Mode_AF_PP;
gpioPB5_Struct.GPIO_Pin = GPIO_Pin_5;
gpioPB5_Struct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &gpioPB5_Struct);
//设置时钟分割
tim3_Struct.TIM_ClockDivision = TIM_CKD_DIV1;
// 设置TIM向上计数模式
tim3_Struct.TIM_CounterMode = TIM_CounterMode_Up;
//设置在下一个更新事件装入活动重装值
tim3_Struct.TIM_Period = 200 -1;
// TIM时钟频率的预分频值
tim3_Struct.TIM_Prescaler = 2700 - 1;
TIM_TimeBaseInit(TIM3, &tim3_Struct);
//配置PWM模式一
motorG90_Struct.TIM_OCMode = TIM_OCMode_PWM1 ;
//配置比较输出使能
motorG90_Struct.TIM_OutputState = TIM_OutputState_Enable ;
// 配置输出极性
motorG90_Struct.TIM_OCPolarity = TIM_OCPolarity_Low ;
TIM_OC2Init(TIM3, &motorG90_Struct);
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_Cmd(TIM3, ENABLE);
}
测试代码:
int main()
{
uint16_t pwmval = 155;
MotorG90_Init();
while(1)
{
for(pwmval=195;pwmval>=175;pwmval-=5)
{
TIM_SetCompare2(TIM3, pwmval);
delay(200);
}
}
}