1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > stm32f4 用一个定时器输出多个不同频率占空比PWM波(含代码)

stm32f4 用一个定时器输出多个不同频率占空比PWM波(含代码)

时间:2021-12-31 08:31:51

相关推荐

stm32f4 用一个定时器输出多个不同频率占空比PWM波(含代码)

之前有写过怎么使用定时器生成PWM波,以及怎么修改频率与占空比,具体大家可以看下面这篇

stm32f4 生成PWM波_居安士的博客-CSDN博客_stm32产生pwm波

STM32每一个定时器都有4路通道,但是通常一个TIM输出的频率是固定了,使用一个定时器通常只能输出同频率不同占空比的PWM波。

但是由于IO口的选择,如果不使用同一个TIM,就需要启用高级定时器(TIM1和TIM8),最后我们尝试先用同一个TIM生成多个不同频率和占空比的PWM波,几经波折,找到了解决方法!

下面我使用的是TIM3的3通道和4通道,对应着PB0和PB1,大家对照着自己的IO口和TIM修改下面我注释的地方:

#include "sys.h"#include "osa.h"//OSA clk : PB0 TIM3_CH3//OSA Reset£ºPB1 TIM3_CH4uint16_t CCR3_Val1 = 200;//修改uint16_t CCR3_Val2 = 200;uint16_t CCR4_Val1 = 800;//修改uint16_t CCR4_Val2 = 1600;void OSA_clk_init(void){NVIC_InitTypeDef NVIC_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;修改RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);GPIO_PinAFConfig(GPIOB,GPIO_PinSource0,GPIO_AF_TIM3); //修改GPIO_PinAFConfig(GPIOB,GPIO_PinSource1,GPIO_AF_TIM3); //修改GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;//修改 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;GPIO_Init(GPIOB,&GPIO_InitStructure); TIM_TimeBaseStructure.TIM_Period = 65535;TIM_TimeBaseStructure.TIM_Prescaler =1;TIM_TimeBaseStructure.TIM_ClockDivision = 0;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);/* Output Compare Toggle Mode configuration: Channel2 */TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitStructure.TIM_Pulse = CCR3_Val1;TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;TIM_OC3Init(TIM3, &TIM_OCInitStructure);TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Disable);/* Output Compare Toggle Mode configuration: Channel3 */TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitStructure.TIM_Pulse = CCR4_Val1;TIM_OC4Init(TIM3, &TIM_OCInitStructure);TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Disable);NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);/* TIM enable counter *//* TIM IT enable */TIM_ITConfig(TIM3,TIM_IT_CC3| TIM_IT_CC4, ENABLE);//修改/* Enable the TIM3 global Interrupt */TIM_Cmd(TIM3, ENABLE);}_Bool CH3_Flag = 0;_Bool CH4_Flag = 0;void TIM3_IRQHandler(void){uint16_t capture1 = 0;uint16_t capture2 = 0;/* TIM3_CH2 toggling with frequency = 732.4 Hz */if (TIM_GetITStatus(TIM3, TIM_IT_CC3) != RESET){TIM_ClearITPendingBit(TIM3, TIM_IT_CC3);capture1 = TIM_GetCapture3(TIM3);if(CH3_Flag == 0){TIM_SetCompare3(TIM3, capture1 + (uint16_t)CCR3_Val2);CH3_Flag = 1;}else{TIM_SetCompare3(TIM3, capture1 + (uint16_t)CCR3_Val1);CH3_Flag = 0;}}/* TIM3_CH3 toggling with frequency = 1464.8 Hz */if (TIM_GetITStatus(TIM3, TIM_IT_CC4) != RESET){TIM_ClearITPendingBit(TIM3, TIM_IT_CC4);capture2 = TIM_GetCapture4(TIM3);if(CH4_Flag == 0){TIM_SetCompare4(TIM3, capture2 + (uint16_t)CCR4_Val2);CH4_Flag = 1;}else{TIM_SetCompare4(TIM3, capture2 + (uint16_t)CCR4_Val1);CH4_Flag = 0;}}}

修改完IO口和TIM,我们只需要动下面这个地方,即修改CCR的值

最终,频率=主频/分频/(CCR1+CCR2)

占空比=CCR1/(CCR1_CCR2)

我们可以按照自己的需要,设置CCR1和CCR2的值

普通定时器主频/分频=84;高级定时器主频/分频=168

举个例子:普通定时器CCR1=CCR2=84,那么频率就是 84/(84+84)=0.5M,占空比=0.5

但是在实验的时候,我们发现,这个代码只能输出低于0.1M频率的PWM波(或许还不够完善?),如果大家需要生成高于这个频率的PWM波,只能选择使用高级定时器(TIM1和TIM8),很不幸,我的项目需要频率高于0.1M,也需要使用高级定时器。。。但是也不算白弄,分享给可以使用的朋友!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。