蓝桥杯定时器主要有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的模式都很重要,最好都可以掌握。