STM32死区计算和配置

文章介绍了死区时间在电机控制中的重要性,防止功率元件同时导通导致损坏。STM32的高级定时器支持死区时间配置,通过TIMx_BDTR寄存器的DTG字段设定,详细阐述了如何根据定时器时钟频率和分频因子计算死区时间,并提供了死区时间计算的实例。
摘要由CSDN通过智能技术生成

目录

死区简介

定时器相关时钟系统

STM32中配置死区时间

明确自己定时器系统时钟

TIMx_BDTR寄存器


死区简介

        通常,大功率电机、变频器等,末端都是由大功率管、IGBT等元件组成的H桥或3相桥,每个桥的上半桥和下半桥是是绝对不能同时导通的。但高速的PWM驱动信号在达到功率元件的控制极时,往往会由于各种各样的原因产生延迟的效果,造成某个半桥元件在应该关断时没有关断,造成功率元件烧毁。死区就是在上半桥关断后,延迟一段时间再打开下半桥或在下半桥关断后,延迟一段时间再打开上半桥,从而避免功率元件烧毁。这段延迟时间就是死区。

        PWM输出时的Dead Zone(死区)作用是在电平翻转时插入一个时间间隔,避免关闭前一个设备和打开后一个设备时因为开关速度的问题出现同时开启状态而增加负荷的情况(在没有彻底关闭前打开了后一个设备),尤其是电流过大时容易造成短路等损坏设备。

 

        当比较单元的比较操作被使能,就会产生波形PHx。PHx经过死区单元,就会输出两路互补的带有死区的PWM波形DTPHx和DTPHx_。PHx、DTPHx、DTPHx_之间的关系如上图,如果没有死区,那么DTPHx和DTPHx_应该是完全互补的。DTPHx的导通时刻是在PHx的基础上延时了1个死区时间,而关闭时刻未变。DTPHx_是在PHx取反的基础上,也将导通时间延迟了1个死区时间,而关断的时间没有发生改变。

        高级定时器的才带有互补输出功能,同时互补信号可以插入死区,也可以使能刹车功能(同时保持高电平),从这些看来高级定时器的pwm天生就是用来控制电机的。STM32H7系列芯片中,TIM1、TIM8、TIM12和TIM15是高级别定时器,支持死区控制功能。高级定时器可以输出三对互补pwm信号外加ch4通道,也就是一共七路。

定时器相关时钟系统

        高级定时器是挂接到APB2上,而通用定时器是挂接到APB1上的。APB1和APB2的区别就要在于时钟频率不同。APB2最高频率允许72MH,而APB1最高频率为36MHZ。通用定时器时钟信号完整的路线应该是下面这样的:

AHB(72mhz)→APB1分频器(默认2)→APB1时钟信号(36mhz)→倍频器(*2倍)→通用定时器时钟信号CK_INT(72mhz)。定时器接下来还有一个分频寄存器:TIMX_PSC(输入时钟频率CK_PSC一般等于CK_INT)经过他的分频后,才是定时器计数的频率CK_CNT。所以真正的计时器时钟频率CK_CNT应该是72mhz/(TIMX_PSC-1)。pwm主要就是控制频率和占空比的:这两个因素分别通过两个寄存器控制:TIMX_ARR和TIMX_CCRX。ARR寄存器就是自动重装寄存器,也就是计数器记到这个数以后清零再开始计,这样pwm的频率就是tim_frequency/(TIMX_ARR-1)。在计数时会不停的和CCRX寄存器中的数据进行比较,如果小于的话是高电平或者低电平,计数值大于CCRX值的话电平极性反相。所以这也就控制了占空比。

在STM32H7系列芯片中,PWM死区时间的设定是通过TIM_BreakDeadTimeConfigTypeDef结构体中的DeadTime参数来实现的,DeadTime参数的单位是计数器时钟周期。

STM32中配置死区时间

明确自己定时器系统时钟

AHB(72mhz)→APB1分频器(默认2)→APB1时钟信号(36mhz)→倍频器(*2倍)→通用定时器时钟频率CK_INT(CK_PSC)(72mhz)。

TIMx_BDTR寄存器

STM32的TIM高级定时器支持互补PWM波形发生,同时它支持插入死区时间和刹车的配置。直接看参考手册里的寄存器TIMx_BDTR,这是配置刹车和死区时间的寄存器;

 DTG寄存器为死区时间存储值。设DTG[7:0] = k;

 

DT:死区时间;T_{DTS}为系统时钟周期时长;Tdtg为系统周期时长乘以倍数,这个值用于计算最终死区时间,也叫作步长。

在72M的定时器时钟下,T_{DTS} = 1/72M = 13.89ns。

这个计算比较复杂,主要思想就是把DTG的八位,掰成两部分用。一部分决定步长(DTG[7:5],决定步长Tdtg是T_{DTS}·的几倍,另一部分是与步长相乘的乘数(不同的步长对应不同的公式),乘数可以自行设定,步长*乘数=死区时间。至于步长与乘数从哪里分开,看上表。

周期13.89ns时,死区范围ns 0~1764 1778~3528 3556~7000 7112~14001

        可以看到死区时间DT由DTG[7:0]决定,这里还有一个问题是T_{DTS}·是什么?在TIMx_CR1的寄存器可以得知,T_{DTS}由TIMx_CR1寄存器的CKD决定;

接下来举例说明表格怎么用。

定时器时钟为72MHz,时钟分频因子为1分频。定时器的时钟周期:TDTS=1/tDTS=1/tCK_INT=1/72MHz=13.89ns.

根据公式可算出可能的死区时间范围如下四种情况:

1.DT=DTG[7:0]×Tdtg,Tdtg=TDTS

DT=(0~127)×13.89ns=0~1763.89ns

2.DT=(64+DTG[5:0])×Tdtg =(64+DTG[7:0] -128)×Tdtg , Tdtg=2×TDTS

DT=(64+(0~63))×2×13.89ns=1777.92ns~3528.06ns

3.DT=(32+DTG[4:0])×Tdtg = (32+DTG[7:0]-192)×Tdtg, Tdtg=8×TDTS

DT=(32+(0~31))×8×13.89ns=3555.84ns~7000.56ns=3.56us~7us

4.DT = (32+DTG[4:0])×Tdtg =(32+DTG[7:0] - 224)×Tdtg  ,Tdtg=16×TDTS

DT=(32+(0~31))×16×13.89ns=7111.68ns~14001.12ns=7.11168us~14us

假如 定时器的工作时钟频率72MHz,时钟分频因子1分频,死区时间设置为2us。则DTG寄存器值为多少?

因为:死区时间2us属于情况2,DTG[7:6] = 0b10,DTG[5:0]寄存器值=2000ns÷(13.89ns*2)-64=7.994240460763139≈8. 二进制为:0x001000.综上所述:DTG[7:0] = 0b10001000 = 0x88=136

假如3us的死区时间,那么属于情况2,DTG[7:6] = 0b10,步长=27.78,需要的乘数 = 3000÷27.78-64=108-64=44=0b101100,DTG[7:0]=0b10101100=0xAC=172。DTG寄存器为死区时间存储值。

实际的系统中,死区的时间一般由硬件的响应速度决定

 

下面是 STM32 标准库的高级定时器(TIM1 和 TIM8)死区功能的配置步骤: 1. 使能定时器时钟,并初始化定时器。 ``` RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); // 使能 TIM1 时钟 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructure.TIM_Period = 999; // 自动重装值 TIM_TimeBaseStructure.TIM_Prescaler = 71; // 时钟预分频 TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); // 初始化 TIM1 TIM_Cmd(TIM1, ENABLE); // 启动 TIM1 ``` 2. 配置死区时间,并使能死区时间。 ``` TIM_BDTRInitTypeDef TIM_BDTRInitStructure; TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Disable; // 关闭内部触发信号 TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Disable; // 关闭内部触发信号 TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF; // 关闭锁定功能 TIM_BDTRInitStructure.TIM_DeadTime = 50; // 死区时间,单位为 TIM 时钟周期 TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); // 初始化 TIM1 的 BDTR ``` 3. 配置输出比较通道,并使能预装载功能。 ``` TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // PWM 模式1 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 使能输出 TIM_OCInitStructure.TIM_Pulse = 499; // 比较值 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // 高电平极性 TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; // 空闲状态为低电平 TIM_OC1Init(TIM1, &TIM_OCInitStructure); // 初始化 TIM1 的通道1 TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); // 使能通道1的预装载功能 ``` 4. 配置 DMA 传输的突发长度,并使能 DMA 传输。 ``` DMA_InitTypeDef DMA_InitStructure; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &TIM1->DMAR; // DMA 传输目标地址 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &ADCValue; // DMA 传输源地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; // 传输方向:从存储器到外设 DMA_InitStructure.DMA_BufferSize = 2; // DMA 传输数据量 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 禁止目标地址自增 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // 允许源地址自增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 目标数据长度为半字 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // 源数据长度为半字 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // 循环传输 DMA_InitStructure.DMA_Priority = DMA_Priority_High; // DMA 优先级 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // 禁用内存到内存传输 DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE); // 允许 DMA 传输完成中断 DMA_Init(DMA2_Stream0, &DMA_InitStructure); // 初始化 DMA DMA_Cmd(DMA2_Stream0, ENABLE); // 启动 DMA ``` 通过上述步骤,就可以实现 STM32 高级定时器的死区功能配置。需要注意的是,具体的配置参数需要根据具体应用来确定,以上仅为参考。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值