蓝桥杯嵌入式—定时器篇(2)(重点)—PWM和输出比较

蓝桥杯定时器主要有TIM1(高级定时器,之后会介绍),TIM2,TIM3。这里以定时器2为例写通用定时器的PWM配置。

要点1

PWM由ARR确定频率,由CCRX寄存器确定占空比。

记得使能IO口的复用时钟。

PWM模式1和PWM模式2的概念:
在这里插入图片描述

配置步骤

1.在数据手册找到TIM2通道对应的IO口。
在这里插入图片描述

2.写初始化函数(注释都很详细)

 void Tim2_PWM_Config(u16 arr,u16 psc)//都是16位的寄存器
{
    
    
 GPIO_InitTypeDef GPIO_InitStructure;
 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
 TIM_OCInitTypeDef TIM_OCInitStructure;
 
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE); //使能复用时钟
 
 TIM_TimeBaseInitStructure.TIM_Period=arr;//自动重装载值设置值的时候要注意减一位
 TIM_TimeBaseInitStructure.TIM_Prescaler=psc;//预分频系数
 TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//计数模式
 TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//定时器初始化
 
 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_2;
 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
 GPIO_Init(GPIOA,&GPIO_InitStructure);
 
 TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;//PWM1模式
 TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//输出状态使能
 TIM_OCInitStructure.TIM_Pulse=500;//设置占空比
 TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;//高电平有效还是低电平有效。
 TIM_OC2Init(TIM2,&TIM_OCInitStructure);
 
 TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;//PWM1模式
 TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//输出状态使能
 TIM_OCInitStructure.TIM_Pulse=700;//设置占空比
 TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;//高电平有效还是低电平有效。
 TIM_OC3Init(TIM2,&TIM_OCInitStructure);
 
 
 TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);//使能预装载寄存器
 TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);//使能预装载寄存器
 
 TIM_Cmd(TIM2,ENABLE);//定时器使能。
}

注:只需改变‘TIM_OCInitStructure.TIM_Pulse’相对的值便可以输出占空比不同的波形。

3.另外必须要掌握和熟练运用的库函数:

void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);//设置计数器的数值
void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload);
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);//设置定时器通道1的比较值,也就是CCR1寄存器的值
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);
void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);
void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4);
uint16_t TIM_GetCapture1(TIM_TypeDef* TIMx);              //得到定时器通道1的比较值
uint16_t TIM_GetCapture2(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture3(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture4(TIM_TypeDef* TIMx);
uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);
uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);		//得到当前定时器的预分频系数

要点2

在蓝桥杯的试题中,有让你使用一个定时器的不同通道产生不同频率的PWM波。上面那样是做不到的。因为‘TIM_TimeBaseInitStructure.TIM_Prescaler=psc;’这个函数已经决定了频率是一定的。要想实现两个通道产生频率和占空比都不同的PWM波,需要用到输出比较模式。有关于输出比较模式的知识看这位大佬
下面是我写的代码和用逻辑分析仪看到的效果:(具体代码我放在这里了)

可以看到两个通道的频率和占空比是不一样的。在这里插入图片描述

注意事项

根据大佬的文章,我写一些注意事项和基本概念:
1.定时器初始化中的预装载寄存器不使能,这和要点1的PWM初始化是不同的。

  TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Disable);
 TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Disable);//预装载寄存器不使能

2.改变定时器的输出模式为 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;,我具体解释下这个模式的含义
在这里插入图片描述
在这里插入图片描述
从这两张图可以看到这个模式作用是:当CCR寄存器的值和CNT计数器的值相等时电平发生翻转。

3.还有一个概念是 **TIM_ITConfig(TIM2,TIM_IT_CC2 | TIM_IT_CC3, ENABLE);**定时器这个中断的含义:当CCR寄存器的值和计数器的值相等时进入中断。

总结

这两种产生PWM的模式都很重要,最好都可以掌握。

猜你喜欢

转载自blog.csdn.net/qq_43690936/article/details/105162640