目录
Counter Period(AutoReload Register)
Trigger Output(TRGO) Parameters
本文旨在记录和说明STM32CubeIde中互补PWM的配置项含义。本人作为STM32新手,在配置互补PWM时,太多的意义不明的配置项让我摸不着头脑,查阅资料并在这里记录,如果有不对的,欢迎各位大佬指正。
本文硬件使用ST官方提供的NUCLEO-G474RE,记录互补PWM的产生过程。
一、调试方式
使用SW的调试方式
Timebase Source:
时基:时基就是为运行程序提供一个时间。比如在HAL库中,存在一些需要提供时钟的函数,比如延时函数,而时基就是为这些需要时钟的函数提供一个时间线,或者说给他计时。裸机运行时,默认使用SysTick作为时钟源,当有操作系统运行时,才会使用其他定时器作为时基。
当使用SysTick作为时基时,stm32g4xx_hal.c中的HAL_Init(void)这样定义:使用systick作为时基源来配置1ms的tick,该函数是一个弱化函数。
/* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */
if(HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK)
{
return HAL_ERROR;
}
二、时钟配置
使用外部24MHz晶振
时钟频率配置乘最快的170MHz
三、配置TIM1高级定时器
高级定时器功能很强大,配置相对复杂,且需要针对对应的硬件去做配置。这里我们主要介绍高级定时器产生6路互补PWM来驱动MOS管,高级定时器1通道1、2、3用于产生6路互补的PWM,配置如下:
选择PWM Generation CHx CHxN,会产生两个引脚,TIM1_CHx产生一路PWM波,TIM1_CHxN产生它的PWM互补波,这样就可以驱动MOS管的上下开关,使得上下开关交替开通。
Counter Setting
Prescaler(PSC)
预分频器:TIM1挂在APB2上,频率为170MHz,通过设置预分频器的值,可以分频出不同频率的时钟源,具体公式如下
PSC为填写的Prescaler的值,如想获取1MHz的时钟,则填写PSC的值为170-1即可,这里我们选择不分频。
Counter Mode
高级定时器的计数模式有三种: 递增计数模式、 递减计数模式和中心对齐模式,我们可以把定时器理解为一个计数器,根据计数模式的不同,计数器有不同的计数形式。
递增计数模式:每过一个时钟周期,计数器的值+1,当计数器的值等于ARR寄存器值时,产生更新事件,称为定时器上溢。
递减计数模式:从ARR寄存器的值开始,每过一个时钟周期,计数器的值-1,当计数器的值等于0时,产生更新事件,称为定时器下溢。
中心对齐模式:该模式下,计数器先从0开始递增,直到计数器值等于ARR-1时,定时器上溢,然后从ARR值开始递减,当计数器值为1时,定时器下溢,依此循环。
中心对齐模式的周期数为2*ARR,而递增和递减计数模式的周期数为ARR+1。
下面通过一张图展示定时器在不同计数模式下,更新事件发生的情况。
中心对齐模式又分为3种模式,其通过TIMx_CR1寄存器的位CMS进行设置,其与占空比无关,只是输出比较中断标志的置位有关。
01:中央对齐模式1 ,计数器交替地向上和向下计数。输出比较中断标志位,只在计数器向下计数时被设置。
10:中央对齐模式2, 计数器交替地向上和向下计数。输出比较中断标志位,只在计数器向上计数时被设置。
11:中央对齐模式3 ,计数器交替地向上和向下计数。输出比较中断标志位,只在计数器向下和向上计数时均被设置。
如图所示:ARR为自动重载寄存器,设置为8;CCR为比较寄存器,设置为4;tim_ocxref为PWM波,其在计数器为CCR时改变输出极性。CCxIF为比较标志,其根据不同的中央对齐模式在向上计数和向下计数到CCR时置位,向上的黑色箭头表示置位发生。
Dithering
抖动模式:PWM模式的有效分辨率可以通过启用抖动模式来提高,使用TIMx_CR1寄存器中的DITHEN位。这适用于CCR(占空比分辨率增加)和ARR (PWM频率分辨率增加)。
简单来说,原本CCR和ARR只有16bit的位数,现在增加4位有效位来表示小数,可以增加他们的分辨率,具体效果如图所示,更详细的使用方式可参考芯片手册。
Counter Period(AutoReload Register)
计数周期(自动重载寄存器/ARR寄存器),当选择递增计数模式时,定时器可以理解为一个跟随时钟不断递增的计数器,每过一个时钟周期,该计数器的值就+1,当计数器的值等于ARR的值时,就会产生更新事件。更新事件的产生时间基本的计算公式为:
递增/递减计数模式的时钟周期数为:ARR+1
中央对齐计数模式的时钟周期数为:2*ARR
Internal Clock Division
内部时钟分频:表示定时器时钟频率与死区时间发生器和数字滤波器使用的死区时间和采样时钟等内部时钟之间的分频比,称为CKD,一般设置为不分频。
Repetition Counter
重复计数器:我们知道定时器发生上溢或者下溢时,会直接生成更新事件。但是有重复计数器的定时器并不完全是这样的,定时器每次发生上溢或下溢时,重复计数器的值会减一,当重复计数器的值为 0 时,再发生一次上溢或者下溢才会生成定时器更新事件。
如果我们设置重复计数器寄存器 RCR 的值为 N,那么更新事件将在定时器发生 N+1 次上溢或下溢时发生。
auto-reload preload
自动重载预装载:ARR寄存器是否具有缓存作用
Disable:在运行过程修改ARR寄存器的值时,ARR 寄存器不进行缓冲,该值会马上被写入 ARR 影子寄存器中,从而直接生效。
Enable:在运行过程修改ARR寄存器的值时,ARR 寄存器进行缓冲,该值不会马上被写入 ARR 影子寄存器中,而是要等到更新事件发生才会被写入 ARR 影子寄存器,这时才生效。
Trigger Output(TRGO) Parameters
暂不清楚
Break(刹车)
刹车模式:所谓刹车(Break, Shut-Down)是指在PWM信号输出过程中,接收到触发信号,停止PWM信号的输出。而PWM信号停止之前之后输出什么状态,则是需要明确设定,避免负载端出现异常。而刹车以及再出发也有相应的控制机制。
参考资料
上面的参考资料已经说的很清楚了,这里对配置项进行一个简单归纳
BPK Polarity
选择BRK的刹车有效电平,也就是选择BKIN管脚作为刹车输入的有效电平。BRK Polarity为High时,BKIN管脚收到上升沿电平后会产生PWM信号输出的刹车;BRK Polarity为Low时,BKIN管脚收到下降沿电平后会产生PWM信号输出的刹车。
BPK Filter
对输入信号进行滤波的滤波因子
BPK Source Configuration
数字输入使能,可以使用数字信号触发
Break_IO mode selection
选择Input,break引脚只可作为输入;选择Bidirectional,break引脚既可以作为break源输入信号,也可以作为mcu产生break后的输出信号。一般选择input即可。
Digital Input Polarity:
0:TIMx_BKIN输入极性不反转(如果BKP为0,低电平激活,如果BKP = 1,高电平激活)
1:TIMx_BKIN输入极性反转(如果BKP = 0,高电平激活,如果BKP = 1,低电平激活)
为触发Bidirectional,有效极性必须设置为低有效,通过BPK和BPIN联合配置可设置。
Dead Time(死区时间)
参考资料
上面的参考资料已经说的很清楚了,这里对配置项进行一个简单归纳
Automatic Output State
位 AOE 是自动输出使能位,如果使能 AOE 位, 那么在我们输入刹车信号后再断开了刹车信号,互补的 PWM 会自动恢复输出,如果不使能 AOE 位,那么在输入刹车信号后再断开了刹车信号,互补的 PWM 就不会恢复输出,而是一直保持刹车信号输入时的状态。一般我们使能该位。
OSSR
OSSR不使能,当互补输出正反两路的一路使能输出而另一路没有使能输出,没有使能输出的一路则输出半关闭高阻态,可以使用内部上下拉控制管脚状态。OSSR使能,当互补输出正反两路的一路使能输出而另一路没有使能输出,没有输出的一路则输出全关闭高阻态,内部上下拉无效。
OSSI
OSSI使能后,CH IDLE STATE和CHN IDLE STATE才有效,用于设定刹车后的管脚状态输出。OSSI不使能,刹车后的管脚输出半高阻态,这时候CH IDLE STATE和CHN IDLE STATE的设置无任何效果。
Lock Configuration
因为PWM常用于控制功率输出负载,如果出现异常STM32程序跑飞,导致配置的寄存器混乱,进一步导致PWM输出异常,则会造成风险。Lock Configuration使能后,会形成保护机制,简而言之就是MCU启动后,代码配置Lock保护级别后,在下次重启前相关输出配置不能被修改。
有三个保护级别,Lock Level 3的保护级别最高。一般采用Lock Level 1即可,会在下次复位前冻结TIMx_BDTR 寄存器中的
DTG/BKE/BKP/AOE/BKF/BK2F/BK2E/BK2P 位,以及TIMx_CR2 寄存器中的OISx/OISxN位。
DeadTime Preload
死区时间预加载使能,使能则进行寄存器缓冲,不使能则不进行缓冲,一般设置为使能。
Dead Time
死区时间的设置,公式为
其中的CKD是通过计数器中的Internal Clock Division设置的,我们一般选择不分频,所以这里为170MHz,设置为17时,死区时间为100ns。
Asymmetrical DeadTime
死区时间对称使能。不使能:死区时间的上升沿和下降沿对称,时间相同。使能则设置下降沿时间,计算方法和死区时间相同,一般设置为不使能。
Clear Input
暂不清楚
PWM Generation
参考资料
Mode
定时器产生 PWM 的方式有许多种,下面我们以边沿对齐模式(即递增计数模式/递减计
数模式)为例, PWM 模式 1 或者 PWM 模式 2 产生 PWM 的示意图, 如下图所示:
模式1表示小于CCR时,PWM波输出有效电平;模式2表示大于CCR时,PWM输出有效电平。
Pulse
占空比设置,就是CCR寄存器的值,我们一般设置为0,在代码中用__HAL_TIM_SetCompare来设置占空比。
当计数模式为向上计数时,PWM输出图例如下,该图ARR=8,CCR不同时的PWM输出为tim_ocxref
占空比计算公式为
1
当计数模式为中心对齐时,PWM输出图例如下,该图ARR=8,CCR不同时的PWM输出为tim_ocxref
占空比计算公式为
Output compare preload
CCR寄存器的预装载使能,不使能不缓冲,使能需要寄存器缓冲。
Fast Mode
暂不清楚
CH\CHN Polarity
这个参数就是控制有效电平的,因为有一些芯片的处理需要的是高电平有效,一些是需要低电平有效,需要根据实际情况进行配置
CH\CHN idle Polarity
CH Idle State为该通道PWM不输出时的状态,与刹车配置有关。
Set为高电平;Reset为低电平。
代码实战
参考资料
特别注意:由于我使用了break刹车并将刹车有效电平设为低电平,所以我们需要将刹车引脚置高才可以输出PWM波
这里我配置了一个输出引脚,将它与刹车引脚短接,并配置它的默认输出为高电平,这样一来,PWM默认可以输出,如果需要刹车,把该输出引脚置低,具体配置如下:
具体测试代码如下:
// 定义PWM周期时间
#define PWM_PERIOD TIM_CLK_MHz*1000000/PWM_FREQUENCY/2
// 6路互补PWM测试,放置到main函数的while循环前
// 生成占空比为20%的PWM波
void PWM_Test(void)
{
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);
HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2);
HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_3);
__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_1,0.2*PWM_PERIOD);
__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_2,0.2*PWM_PERIOD);
__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_3,0.2*PWM_PERIOD);
}
插入代码位置如下图
这样就生成了30KHz,占空比为20%,死区时间为100ns的PWM互补波了,如下图
那么就结束了,欢迎大家批评指正。