一直对定时器理解不是很彻底,今天看到一段讲解(原文链接),很好,记录顺便分享一下:
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
这6句话就把PWM的通道配置好了,一句句来解释:
PWM1和PWM2模式是由CCMR1的OC1M和OC2M来决定的,因为我们选择的是是通道2,所以设置的是OC2M,再看相关介绍
OC1M[2:0]:输出比较1模式(Output compare 1 enable)
110:PWM模式1- 在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为有效电平,否则为无效电平;
111:PWM模式2- 在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为无效电平,否则为有效电平;
有效电平是由CCER这个寄存器的CCxP来决定的,这里是通道2,所以是CC2P。
CC1P
0:OC1高电平有效
1:OC1低电平有效
第五句是说,CCR2中的预装载值何时被传送到当前的CNT寄存器中,这里我们选择的是当更新事件到来的时候才装载,追踪寄存器的设置可知,原来设置的是CCMR1的OC2PE,其实还有一种方式是立即装载看手册:
OC1PE
0:禁止TIMx_CCR1寄存器的预装载功能,可随时写入TIMx_CCR1寄存器,并且新写入的数值立即起作用。
1:开启TIMx_CCR1寄存器的预装载功能,读写操作仅对预装载寄存器操作,TIMx_CCR1的预装载值在更新事件到来时被传送至当前寄存器中。
对应的是TIM1_TimeBaseStructure.TIM_Period,如果之后的周期不变,则该函数不用写。
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
使能TIM3在CCR2上的预装载寄存器,即TIM3_CCR2的预装载值在更新事件到来时才能被传送至当前寄存器中。
这句话是说,CCR2中的预装载值何时被传送到当前的CNT寄存器中,这里我们选择的是当更新事件到来的时候才装载。对应的是TIM1_OCInitStructure.TIM_Pulse,设置的是CCMR1的OC2PE,其实还有一种方式是立即装载看手册:P248-249
OC1PE
0:禁止TIMx_CCR1寄存器的预装载功能,可随时写入TIMx_CCR1寄存器,并且新写入的数值立即起作用。
1:开启TIMx_CCR1寄存器的预装载功能,读写操作仅对预装载寄存器操作,TIMx_CCR1的预装载值在更新事件到来时被传送至当前寄存器中。
TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t)
判断定时器TIMx的中断类型TIM_IT是否发生中断。例如判断定时器3是否发生更新(溢出)中断:if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET){}
voidTIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT)
清除定时器TIMx的中断TIM_IT标志位。例如清除TIM3的溢出中断:
固件库还提供了两个函数用来判断定时器状态以及清除定时器状态标志位的函数TIM_GetFlagStatus和TIM_ClearFlag,他们的作用和前面两个函数的作用类似。只是在TIM_GetITStatus函数中会先判断这种中断是否使能,使能了才去判断中断标志位,而TIM_GetFlagStatus直接用来判断状态标志位。(原文)