STM32标准库+HAL库 |
您所在的位置:网站首页 › pwm控制如何改变输出的频率和幅值 › STM32标准库+HAL库 |
提醒:在本文的标准库PWM频率、占空比调节实验所使用的开发板为STM32F407,HAL库PWM调节实验使用的开发板为STM32G431。已实现PWM输出步进1%调节PWM占空比。如果看不懂,可以先跳过原理部分,先copy代码体验一下。如果需要实现精确调节PWM的输出频率及占空比,这些是必须要掌握的。 ST官方在2022年更新了尘封已久的STM32标准库,新版标准库和上一版本没有很大的区别,主要是对一些Bug进行了修复。 STM32标准外设软件库 - 意法半导体STMicroelectronics 目录 1、TIM-PWM参数配置讲解 2、PWM调节STM32 HAL库版 3、PWM调节STM32标准库版 1、TIM-PWM参数配置讲解在许多仪器仪表产品中,需要对PWM进行非常精确、频繁的操作,如果每次都是搬出公式来计算再填入数值,非常的耗时,并且容易算错。因此,将PWM输出频率和占空比封装成一个通用接口,可以极大的减少工作量。 在写这篇博客时,发现目前还没有大佬将TIM-PWM调节的HAL库和标准库归类讲解开源出来,并且没有将封装成一个通用接口,实现一个代码接口函数一键配置PWM的输出频率、占空比,实现真正的灵活、动态调整PWM。 频率值:由计数值决定; 占空比:由比较值决定; 预分频器值 PSC:分频定时器的输入时钟,改变计数器的计数速率,prescaler 自动重装载值 ARR, 也就是 counter period 这个看不懂没关系,了解一下就行,后面会详细简单的说。 PWM是基于TIM的配置实现的,要实现精确修改PWM的输出频率和占空比,需要先了解如何实现TIM定时器精准定时。接下来以配置1ms精确定时来说明如何填写TIM配置的数值。 配置CPU主频为80MHz,APB1和APB2总线分频系数为1,定时1ms。 通过以上计算可知,无论是标准库还是HAL库,在对应TIM定时器配置上将prescaler填入数值:80-1,period(自动重装载值填入):1000-1,就可以实现TIM定时器定时1ms的参数配置。 脉冲宽度调制模式可以生成一个信号,该信号频率由自动重装载寄存器(TIMx_ARR)寄存器值决定,其占空比则由捕获/比较寄存器(TIMx_CRx)寄存器决定。 ------------------------------------------------------------------------------------------- PWM频率:Freq = 定时器时钟主频 / [(ARR+1) * (PSC+1)] PWM占空比: Duty = Pluse / (ARR+1) Pulse 是 捕获/比较寄存器(CCR)的值 ------------------------------------------------------------------------------------------- 提醒:16位的ARR自动重装载值的最大值65535 2、PWM调节STM32 HAL库版通过上一部分讲解的公式计算,配置PA1引脚输出:频率为100Hz,占空比为50%的PWM波。 HAL库版本配置PWM,在STM32CubeMX中,选中PA1引脚,进行TIM2_CH2的GPIO引脚配置 选中TIM2,进行TIM定时器的参数配置。 计算输出占空比参数配置 如果每次配置PWM输出频率和占空比,都和上图一样进行公式计算,手动配置,极其的不方便,很可能因粗心等原因计算错误,因此将公式封装成一个HAL库通用接口。在程序代码中灵活自由的修改PWM输出的频率及占空比。 如下代码为HAL库版本的PWM输出参数配置通用接口 如果使用的芯片MCU频率配置不同,那么将prescaler和clk_freq修改,其它保持不变即可。 例:MCU频率配置为64MHz,APB1和APB2均是1分频, 修改tim_clk_freq = 64000000; prescaler = 64-1; //通用接口,主频80MHz,预分频值为80-1,设置PWM的脉冲频率freq(0.16-10kHz)、占空比参数 pulse (0-100) void set_pwm_param(TIM_HandleTypeDef htim, uint32_t Channel, uint32_t freq, uint16_t duty) { uint16_t prescaler = 80-1; uint64_t tim_clk_freq = 80000000; //计算PWM频率,所对应的自动重装载值 ---> ARR = 主频 / (预分频+1) / 预期PWM频率(Hz) - 1 float pwm_freq_arr = (tim_clk_freq * 1.0) / (prescaler+1) / freq * 1.0 - 1; //计算PWM占空比,所对应比较寄存器的值 ---> CCR = 预期占空比 * (自动重装载值+1) //占空比则由捕获/比较寄存器(TIMx_CRx)寄存器决定。占空比:duty = Pluse / (ARR+1) float pwm_duty_pulse = duty * 1.0 / 100 * (pwm_freq_arr + 1); //配置PSC预分频值 __HAL_TIM_SET_PRESCALER(&htim, prescaler); //配置PWM频率 ARR __HAL_TIM_SetAutoreload(&htim, (uint16_t)pwm_freq_arr); //配置PWM占空比 __HAL_TIM_SetCompare(&htim, Channel, (uint16_t)pwm_duty_pulse); printf("pwm_freq_arr:%.2f\r\n", pwm_freq_arr); printf("pwm_duty_pulse:%.2f\r\n", pwm_duty_pulse); }使用逻辑分析仪解析PWM波:逻辑分析仪使用配置,PulseView通信波形解析-CSDN博客 HAL库版本的精确动态调整PWM频率占空比: 频率:20Hz 占空比:1% set_pwm_param(htim2, TIM_Channel_2, 20, 1); HAL库版本的精确动态调整PWM频率占空比: 频率:10kHz 占空比:99% set_pwm_param(htim2, TIM_Channel_2, 10000, 99); 通过STM32F4xx官方参考手册可知,在STM32F407中,定时器TIM3挂载在APB1总线上。当APB1和APB2分频数为1的时候,TIM1、TIM8~TIM11的时钟为APB2的时钟,TIM2~TIM7、TIM12~TIM14的时钟为APB1的时钟;当APB1和APB2分频数不为1,那么TIM1、TIM8~TIM11的时钟为APB2的时钟的两倍,TIM2~TIM7、TIM12~TIM14的时钟为APB1的时钟的两倍。 查看STM32的system_stm32f4xx.c文件,可确定STM32F407的APB1和APB2总线的时钟分频。
如下代码为标准库版本的PWM输出参数配置通用接口 如果使用的芯片MCU频率配置不同,那么将prescaler和clk_freq修改,其它保持不变即可。 例:MCU频率配置为64MHz,代码中自动进行APB1和APB2时钟判断 修改 tim_clk_freq = 64000000; prescaler = 64-1; //通用接口,主频168MHz,预分频值根据ABPx总线配置,设置PWM的脉冲频率freq(0.16-10kHz)、占空比参数 pulse (0-100) void set_pwm_param(TIM_TypeDef* TIMx, uint32_t Channel, uint32_t freq, uint16_t duty) { uint16_t prescaler = 168 - 1; //预分频值 uint64_t tim_clk_freq = 168000000; //定时器时钟频率 float pwm_freq_arr; float pwm_duty_pulse; //系统时钟分频系数不为1 if((TIMx >= TIM2 && TIMx =TIM12 && TIMx= TIM8 && TIMx |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |