STM32标准库+HAL库

您所在的位置:网站首页 pwm控制如何改变输出的频率和幅值 STM32标准库+HAL库

STM32标准库+HAL库

2024-05-28 01:03| 来源: 网络整理| 查看: 265

提醒:在本文的标准库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);

3、PWM调节STM32标准库版

        通过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总线的时钟分频。

      因为系统初始化SystemInit函数里初始化APB1总线时钟为4分频即42M,APB2总线时钟为2分频即84M,所以TIM1、TIM8~TIM11的时钟为APB2时钟的两倍即168M,TIM2~TIM7、TIM12~TIM14的时钟为APB1的时钟的两倍即84M。

如下代码为标准库版本的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