前言
文章的主要目的就是介绍HRTIM的相关使用以及配置过程。相较于普通TIM,HRTIM最显著的特点就是可以倍频到最大的32倍,像F334可以达到4.68GHZ, G474可以达到5.44GHZ, 这就可以使得定时器即使工作在较高频率下,仍有较高的分辨率。 因此它主要用于数字电源、照明,电源耗材,太阳能逆变器 ,射频电路 和无线充电等应用场合。
所用工具:
- 开发模组:STM32G474RE
- 开发环境:STM32CubeMX最新版+Keil5
HRTIM的基本构成
1.构成
由主定时器 Master Timer,独立定时器(Timer A~Timer F)组成,主定时器一般用于同步其他独立定时器,为什么需要同步呢?应为独立定时器每一个都是独立工作的,每个定时器都存在一定的误差,所以这时候每个定时器之间就不会同步了,这时候就可以让主定时器来介入,复位独立定时器来达到同步的目的。
2.主定时器(Master Timer):
基于 16 位递增计数器。它可通过 4 个比较单元置位/ 复位 定时器的输出,并向其他独立定时器单元(Timer A~Timer F)提供同步信号。其主要用途是使定时器单元受唯一的时钟源控制。全桥Buck-Boost数字电源是一个典型的应用示例,主定时器在其中管理多个单元之间的相移。
3.独立定时器(Timer A~Timer F):
既可以独立工作,也可以与其它定时器(包括主定时器)配合工作。每个定时器都可控制两路输出。输出置位/复位事件可以由定时单元比较寄存器触发,或者由主定时器事件、其他定时器的事件或外部事件触发。每个定时器的两路输出:
1)支持PWM互补输出,支持添加死区时间。
2)将载波频率添加到调制信号上。
3)通过将异步输出置为预定义的安全电平来管理故障事件。
4.外部事件(可用于任何定时器单元)
可编程极性和边沿有效性。
5个事件用于快速异步模式。
5个事件用于可编程数字滤波器。
利用消隐和窗口模式实现伪事件过滤。
5.通道(连接到内置模拟外设)
4个用于 ADC 转换器的触发信号。
3个用于 DAC 转换器的触发信号。
3个用于比较器。
6.保护机制
5 路故障输入可组合使用,而且可以关联到任何定时单元。
可编程极性和边沿有效性。
对谐振变换器配有专门的延时保护。
STM32CubeMX HRTIM配置
时钟源配置
时钟树配置(我这里用的是外部8M晶振,如果用默认的配置只能到150M)
HRTIM配置
开启主定时器(Master Timer)
1.选择其他合适的独立定时器,
3.选择的是TimerE 通道1和通道二,后面要配置互补,不需要互补选择一个通道就好
4.选择的是Timer F通道1和通道二,后面要配置互补,不需要互补选择一个通道就好
1.选择HRTIM选项卡
2.设置主定时器
3.选择合适的倍频数或分频数
4.设置周期计数器长度得以得出控制频率
5.使能预加载寄存器
6.使能更新重复
中断在这里不开,应为频率特别高,开中断会影响程序正常运行
开启独立定时器(Timer A~Timer F)
相同方式 选择合适的倍频数或分频数
设置周期计数器长度得以得出控制频率
第6步是配置重置触发源,这里选择:计时器计数器在主计时器周期事件时重置,也就是主定时器溢出是进行重置
这里如果要设置死区,就选择:死区时间插入输出1和输出2之间
设置比较通道,这里的比较值也是有限制的,具体可以查看手册,两个比较值之间太短了输出PWM会有问题的,具体原因看下手册吧,手册这么写的,设置在这个范围内吧,具体为什么存在这个范围我也不清楚,没找到相关文档。
使能死区时间配置
选择分频系数
设置死区时间
死区在上升沿还是下降沿
设置有效输出电频
设置源:复位源、启动源
TimerF是一样的配置就不过多的重复了
接下来生成工程
主函数初始化之后调用如下代码可以启动定时器输出:
HAL_HRTIM_WaveformOutputStart(&hhrtim1, HRTIM_OUTPUT_TE2 + HRTIM_OUTPUT_TE1 + HRTIM_OUTPUT_TF1 + HRTIM_OUTPUT_TF2);
HAL_HRTIM_WaveformCounterStart(&hhrtim1, HRTIM_TIMERID_MASTER + HRTIM_TIMERID_TIMER_E + HRTIM_TIMERID_TIMER_F);
停止定时器输出:
HAL_HRTIM_WaveformOutputStop(&hhrtim1, HRTIM_OUTPUT_TE2 + HRTIM_OUTPUT_TE1 + HRTIM_OUTPUT_TF1 + HRTIM_OUTPUT_TF2);
HAL_HRTIM_WaveformCounterStop(&hhrtim1, HRTIM_TIMERID_MASTER + HRTIM_TIMERID_TIMER_E + HRTIM_TIMERID_TIMER_F);
如果需要更改比较器比较值或者重装载值:
//更改重装载值
__HAL_HRTIM_SETPERIOD(&hhrtim1, HRTIM_TIMERINDEX_MASTER, _period);
__HAL_HRTIM_SETPERIOD(&hhrtim1, HRTIM_TIMERINDEX_TIMER_E, _period);
__HAL_HRTIM_SETPERIOD(&hhrtim1, HRTIM_TIMERINDEX_TIMER_F, _period);
//更改比较值
__HAL_HRTIM_SETCOMPARE(&hhrtim1, HRTIM_TIMERINDEX_TIMER_E , HRTIM_COMPAREUNIT_1, a1);
__HAL_HRTIM_SETCOMPARE(&hhrtim1, HRTIM_TIMERINDEX_TIMER_E, HRTIM_COMPAREUNIT_3, a2);
__HAL_HRTIM_SETCOMPARE(&hhrtim1, HRTIM_TIMERINDEX_TIMER_F , HRTIM_COMPAREUNIT_1, b1);
__HAL_HRTIM_SETCOMPARE(&hhrtim1, HRTIM_TIMERINDEX_TIMER_F, HRTIM_COMPAREUNIT_3, b2);
到这篇文章的重点了,两两互补,组成全桥,再加上移相如何去操作呢?新手可能比较蒙。
看下面代码吧,调用这两个函数就可以得到两两互补加移相的波型了
#define HRTIMCLOCKFREQ 5440000000
typedef struct
{
uint32_t freq; //频率
uint32_t proportion; //占空比
float angle;// 移相角度
}tim_struct;
typedef struct
{
uint32_t period;
uint32_t a1;
uint32_t a2;
uint32_t b1;
uint32_t b2;
}pwm_para;
void cmp_by_angle(tim_struct * tm, pwm_para * pwm)
{
//计算重装载值
uint32_t _period = HRTIMCLOCKFREQ / tm->freq;
pwm->period = _period;
//计算基准比较值
uint32_t _cmp = _period * tm->proportion / 100;
pwm->a1 = _cmp;
pwm->a2 = _period;
//计算偏移度
uint32_t _shifting = _cmp + _period * tm->angle / 360;
if(_shifting > _period) _shifting %= _period;
pwm->b1 = _shifting;
_shifting = _shifting + _cmp;
if(_shifting > _period) _shifting %= _period;
pwm->b2 = _shifting;
//rt_kprintf("b1:%d, b2:%d, c1:%d, c3:%d\n", pwm->a1, pwm->a2, pwm->b1, pwm->b2);
return;
}
void set_pwm_value(pwm_para * pwm)
{
uint32_t _period = pwm->period, a1 = pwm->a1, a2 = pwm->a2, b1 = pwm->b1, b2 = pwm->b2;
__HAL_HRTIM_SETPERIOD(&hhrtim1, HRTIM_TIMERINDEX_MASTER, _period);
__HAL_HRTIM_SETPERIOD(&hhrtim1, HRTIM_TIMERINDEX_TIMER_E, _period);
__HAL_HRTIM_SETPERIOD(&hhrtim1, HRTIM_TIMERINDEX_TIMER_F, _period);
__HAL_HRTIM_SETCOMPARE(&hhrtim1, HRTIM_TIMERINDEX_TIMER_E , HRTIM_COMPAREUNIT_1, a1);
__HAL_HRTIM_SETCOMPARE(&hhrtim1, HRTIM_TIMERINDEX_TIMER_E, HRTIM_COMPAREUNIT_3, a2);
__HAL_HRTIM_SETCOMPARE(&hhrtim1, HRTIM_TIMERINDEX_TIMER_F , HRTIM_COMPAREUNIT_1, b1);
__HAL_HRTIM_SETCOMPARE(&hhrtim1, HRTIM_TIMERINDEX_TIMER_F, HRTIM_COMPAREUNIT_3, b2);
}
好了,文章到这里就结束了,接下来还有DMA+HRTIM的使用文章待更新,可以点个关注!