注:本文为 "STM32 HRTIM" 相关合辑。
图片清晰度受引文原图所限。
略作重排,未整理去重。
如有内容异常,请看原文。
STM32H7 高分辨率定时器 HRTIM 基础原理与 HAL 应用程序接口
硬汉嵌入式
2020-02-29 14:41:56
本文阐述高分辨率定时器(High-Resolution Timer, HRTIM)硬件原理与配套 HAL 库应用程序接口规范。
1 入门前置说明
- HRTIM 外设可输出至多 10 路高精度时序信号,典型应用场景包含数字电源、照明驱动、光伏逆变器、无线充电装置,同时可作为通用定时外设使用。
- HRTIM 采用模块化硬件架构,支持独立波形生成或多路波形叠加输出;结合片内时序控制单元与多路外部事件输入,可生成脉冲宽度调制(PWM)、移相脉冲等各类时序波形。
- HRTIM 集成时序测量功能,可与片内模数转换器(ADC)、数模转换器(DAC)建立硬件触发链路;内置轻载运行控制逻辑与多路故障处理电路,可实现硬件级安全关断。
- HRTIM 提供多路独立中断服务入口,工程开发阶段需匹配对应中断函数:
c
HRTIM1_Master_IRQHandler
HRTIM1_TIMA_IRQHandler
HRTIM1_TIMB_IRQHandler
HRTIM1_TIMC_IRQHandler
HRTIM1_TIMD_IRQHandler
HRTIM1_TIME_IRQHandler
HRTIM1_FLT_IRQHandler
2 HRTIM 硬件基础原理
HRTIM 硬件由 6 路定时单元构成,包含 1 路主定时单元(Master Timer)与 5 路独立子定时单元 Timer A ~ Timer E。
- 全部 6 路定时单元均为 16 bit 计数架构,每路单元内置独立计数器与 4 组比较寄存器。
2.1 主定时单元(Master Timer)
主定时单元基于 16 bit 递增计数器工作,可通过内部 4 组比较寄存器完成 10 路输出通道的置位、复位操作,同时向 5 路子定时单元输出同步基准信号。
主定时单元作用为统一全部子定时单元的时钟基准,交错式降压变换器为典型应用场景,通过主定时单元完成多路子单元输出波形的移相控制。
2.2 子定时单元 Timer A ~ Timer E
子定时单元支持独立运行模式,或与主定时单元、其余子定时单元联动工作;每路子单元可驱动两路输出通道。输出置位、复位触发源包含单元内部比较寄存器、主定时单元事件、其余子定时单元事件、外部硬件事件四类。
单路子单元两路输出通道具备下述能力:
- 互补 PWM 波形输出,支持硬件死区时间插入;
- 可在调制波形上叠加高频载波信号;
- 故障事件触发时,异步将输出强制配置为预设安全电平。
2.3 外部事件输入
外设集成 10 路外部事件输入通道,可接入任意定时单元,配置参数包含信号极性、有效边沿;
- 5 路通道支持高速异步响应;
- 5 路通道集成可编程数字滤波电路;
- 内置消隐区间、窗口检测机制,滤除无效干扰脉冲。
2.4 模拟外设硬件触发链路
多路硬件触发通道连接片内模拟外设:
- 4 路信号用于 ADC 转换触发;
- 3 路信号用于 DAC 更新触发;
- 3 路信号用于片内比较器事件捕获。
2.5 硬件保护机制
- 5 路故障输入通道支持多路逻辑组合,可关联至任意定时单元;
- 每路故障输入可独立配置极性与有效检测边沿;
- 针对谐振变换器拓扑设计专用延时保护逻辑。
2.6 多片 HRTIM 同步链路
不同芯片的 HRTIM 外设可通过同步输入、同步输出引脚完成时序同步。
2.1 HRTIM 硬件结构框图
外设硬件框图为理解外设信号通路的标准方式,可直观梳理外设全部硬件功能,寄存器细节可查阅芯片参考手册补充。

框图内信号接口定义如下:
hrtim_in_sync[3:1]:同步输入总线,用于将本机 HRTIM 与其余片内、片外定时外设同步hrtim_in_sync[1]:保留位;hrtim_in_sync[2]:同步源为片内通用 TIMx 定时器(片内互连总线);hrtim_in_sync[3]:同步源为外部芯片 HRTIM(引脚 HRTIM_SCIN)。
hrtim_out_sync[2:1]:同步输出总线,用于多片 HRTIM 级联同步;STM32H7 单片仅集成 1 组 HRTIM,仅可同步外部芯片 HRTIM。hrtim_out_sync[1]:保留位;hrtim_out_sync[2]:同步输出至外部外设(引脚 HRTIM_SCOUT)。
hrtim_adc_trg[4:1]:ADC 转换触发输出总线;hrtim_dac_trg[3:1]:DAC 更新触发输出总线;hrtim_mst_it[7:1]:中断请求输出总线;hrtim_dma[6:1]:DMA 请求输出总线;hrtim_pclk:APB 外设时钟输入;hrtim_ker_ck:HRTIM 内核时钟输出;hrtim_evtX[4:1](X 取值范围 1 ≤ X ≤ 10 1 \le X \le 10 1≤X≤10):外部事件输入总线,共 10 路事件通道,每路通道可选 4 类输入源,输入源分为片内外设(比较器、ADC 模拟看门狗、通用 TIMx、定时器触发输出)、片外引脚(HRTIM_EEVx)两类。

HRTIM_FLT[5:1]/hrtim_in_flt[5:1]:故障输入总线,包含 5 路片内故障信号、5 路片外引脚 HRTIM_FLTx;输入信号有效时,硬件立即关断全部 HRTIM 输出通道。hrtim_sys_flt:系统级故障输入,包含时钟安全系统、SRAM 奇偶校验错误、Cortex®-M7 LOCKUP(硬件故障)、可编程电压检测器(PVD)输出等信号。hrtim_upd_en[3:1]:寄存器更新使能输入(片内互连总线),触发影子寄存器数据同步至运行寄存器。hrtim_bm_trg:突发模式触发事件输入;hrtim_bm_ck:突发模式时钟输入;- 输出引脚组:
HRTIM_CHA1、HRTIM_CHA2、HRTIM_CHB1、HRTIM_CHB2、HRTIM_CHC1、HRTIM_CHC2、HRTIM_CHD1、HRTIM_CHD2、HRTIM_CHE1、HRTIM_CHE2,分别对应 Timer A ~ Timer E 的两路输出通道。
2.2 HRTIM 时钟源配置
HRTIM 支持两类时钟输入源:通用定时器时钟、处理器内核主时钟。

时钟源通过宏定义参数区分:
c
#define RCC_HRTIM1CLK_TIMCLK ((uint32_t)0x00000000)
#define RCC_HRTIM1CLK_CPUCLK RCC_CFGR_HRTIMSEL
- 参数
RCC_HRTIM1CLK_CPUCLK:时钟源为处理器内核主频; - 参数
RCC_HRTIM1CLK_TIMCLK:时钟源为通用定时器时钟;处理器主频配置为 400 MHz 400 \ \text{MHz} 400 MHz 时,通用定时器时钟为 200 MHz 200 \ \text{MHz} 200 MHz。
时钟配置调用函数 HAL_RCCEx_PeriphCLKConfig,示例代码如下:
c
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_HRTIM1;
PeriphClkInitStruct.Hrtim1ClockSelection = RCC_HRTIM1CLK_TIMCLK;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
2.3 主定时单元硬件框图

主定时单元硬件特征:
- 内置 1 路计数器、4 组比较寄存器,无捕获单元与物理输出通道;
- 主定时单元控制寄存器包含主单元、Timer A ~ Timer E 全部定时单元的使能控制位。
2.4 子定时单元 Timer A ~ Timer E 硬件框图
Timer A ~ Timer E 硬件架构完全一致。

子定时单元硬件特征:
- 内置 1 路计数器、4 组比较寄存器、2 组捕获寄存器,配套两路物理输出通道;
- 第 2、4 组比较寄存器支持硬件延时功能;
- 消隐区间、窗口检测硬件电路实现干扰脉冲过滤;
- 重复计数事件、4 组比较事件、计数器更新事件均可配置为输出通道置位/复位触发源。
2.5 HRTIM 时序分辨率参数
STM32H7 处理器主频配置为 400 MHz 400 \ \text{MHz} 400 MHz 时,HRTIM 内核时钟最大为 400 MHz 400 \ \text{MHz} 400 MHz;H7 系列 HRTIM 不支持倍频配置,仅支持 1、2、4 分频模式。

STM32H7、STM32F3、STM32G4 分辨率参数对比:

STM32G4 系列时序分辨率为三款器件最优,最小时序步长可达 184 ps 184 \ \text{ps} 184 ps。
2.6 PWM 多路输出硬件实现原理
2.6.1 单路 PWM 波形生成逻辑

寄存器 HRTIM_PERxR 存储定时单元周期计数值,寄存器 HRTIM_CMP1xR 存储比较阈值,波形生成流程:
- 计数器计数值等于
HRTIM_CMP1xR时,HRTIM_CHD1输出通道复位; - 计数器计数值等于
HRTIM_PERxR周期值时,HRTIM_CHD1输出通道置位,计数器清零并重新递增计数。
单路 PWM 波形对应硬件通路框图:

2.6.2 多路 PWM 波形生成逻辑

波形时序说明:
- 上半部分波形为 Timer D 两路输出:
HRTIM_CHD1:置位触发源为计数器更新事件,复位触发源为 CMP1 比较事件;HRTIM_CHD2:置位触发源为计数器更新事件,复位触发源为 CMP2 比较事件。
- 下半部分波形为 Timer A 两路输出:
HRTIM_CHA1:置位触发源为计数器更新事件,复位触发源为 CMP1 比较事件;HRTIM_CHA2:置位触发源为 CMP2 比较事件,复位触发源为 CMP3 比较事件、计数器更新事件。
3 HRTIM HAL 库配置规范
HRTIM HAL 库开发流程依托结构体参数配置实现,配套 GPIO、外设时钟、中断、DMA 资源初始化,本节分模块说明全部配置结构体与调用流程。
3.1 寄存器映射结构体 HRTIM_TypeDef
HRTIM 全部寄存器通过结构体 HRTIM_TypeDef 完成地址映射,定义文件为 stm32h743xx.h:
c
typedef struct {
HRTIM_Master_TypeDef sMasterRegs;
HRTIM_Timerx_TypeDef sTimerxRegs[5];
uint32_t RESERVED0[32];
HRTIM_Common_TypeDef sCommonRegs;
} HRTIM_TypeDef;
typedef struct
{
__IO uint32_t MCR;
__IO uint32_t MISR;
__IO uint32_t MICR;
__IO uint32_t MDIER;
__IO uint32_t MCNTR;
__IO uint32_t MPER;
__IO uint32_t MREP;
__IO uint32_t MCMP1R;
uint32_t RESERVED0;
__IO uint32_t MCMP2R;
__IO uint32_t MCMP3R;
__IO uint32_t MCMP4R;
uint32_t RESERVED1[20];
} HRTIM_Master_TypeDef;
typedef struct
{
__IO uint32_t TIMxCR;
__IO uint32_t TIMxISR;
__IO uint32_t TIMxICR;
__IO uint32_t TIMxDIER;
__IO uint32_t CNTxR;
__IO uint32_t PERxR;
__IO uint32_t REPxR;
__IO uint32_t CMP1xR;
__IO uint32_t CMP1CxR;
__IO uint32_t CMP2xR;
__IO uint32_t CMP3xR;
__IO uint32_t CMP4xR;
__IO uint32_t CPT1xR;
__IO uint32_t CPT2xR;
__IO uint32_t DTxR;
__IO uint32_t SETx1R;
__IO uint32_t RSTx1R;
__IO uint32_t SETx2R;
__IO uint32_t RSTx2R;
__IO uint32_t EEFxR1;
__IO uint32_t EEFxR2;
__IO uint32_t RSTxR;
__IO uint32_t CHPxR;
__IO uint32_t CPT1xCR;
__IO uint32_t CPT2xCR;
__IO uint32_t OUTxR;
__IO uint32_t FLTxR;
uint32_t RESERVED0[5];
} HRTIM_Timerx_TypeDef;
typedef struct
{
__IO uint32_t CR1;
__IO uint32_t CR2;
__IO uint32_t ISR;
__IO uint32_t ICR;
__IO uint32_t IER;
__IO uint32_t OENR;
__IO uint32_t ODISR;
__IO uint32_t ODSR;
__IO uint32_t BMCR;
__IO uint32_t BMTRGR;
__IO uint32_t BMCMPR;
__IO uint32_t BMPER;
__IO uint32_t EECR1;
__IO uint32_t EECR2;
__IO uint32_t EECR3;
__IO uint32_t ADC1R;
__IO uint32_t ADC2R;
__IO uint32_t ADC3R;
__IO uint32_t ADC4R;
__IO uint32_t RESERVED0;
__IO uint32_t FLTINR1;
__IO uint32_t FLTINR2;
__IO uint32_t BDMUPR;
__IO uint32_t BDTAUPR;
__IO uint32_t BDTBUPR;
__IO uint32_t BDTCUPR;
__IO uint32_t BDTDUPR;
__IO uint32_t BDTEUPR;
__IO uint32_t BDMADR;
} HRTIM_Common_TypeDef;
结构体成员地址偏移与芯片寄存器地址一一对应。
修饰符 __IO 等价于标准 C 关键字 volatile,标识变量为非易失存储,编译器禁止对该变量进行读写优化;宏定义位于 core_m7.h:
c
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
外设基地址宏定义(stm32h743xx.h):
c
#define PERIPH_BASE (0x40000000UL)
#define D2_APB2PERIPH_BASE (PERIPH_BASE + 0x00010000UL)
#define HRTIM1_BASE (D2_APB2PERIPH_BASE + 0x7400UL)
#define HRTIM1_TIMA_BASE (HRTIM1_BASE + 0x00000080UL)
#define HRTIM1_TIMB_BASE (HRTIM1_BASE + 0x00000100UL)
#define HRTIM1_TIMC_BASE (HRTIM1_BASE + 0x00000180UL)
#define HRTIM1_TIMD_BASE (HRTIM1_BASE + 0x00000200UL)
#define HRTIM1_TIME_BASE (HRTIM1_BASE + 0x00000280UL)
#define HRTIM1_COMMON_BASE (HRTIM1_BASE + 0x00000380UL)
#define HRTIM1 ((HRTIM_TypeDef *) HRTIM1_BASE)
#define HRTIM1_TIMA ((HRTIM_Timerx_TypeDef *) HRTIM1_TIMA_BASE)
#define HRTIM1_TIMB ((HRTIM_Timerx_TypeDef *) HRTIM1_TIMB_BASE)
#define HRTIM1_TIMC ((HRTIM_Timerx_TypeDef *) HRTIM1_TIMC_BASE)
#define HRTIM1_TIMD ((HRTIM_Timerx_TypeDef *) HRTIM1_TIMD_BASE)
#define HRTIM1_TIME ((HRTIM_Timerx_TypeDef *) HRTIM1_TIME_BASE)
#define HRTIM1_COMMON ((HRTIM_Common_TypeDef *) HRTIM1_COMMON_BASE)
寄存器访问示例:
c
HRTIM1->sMasterRegs.MCR = 0;
3.2 全局初始化结构体 HRTIM_InitTypeDef
该结构体用于外设全局同步、中断基础配置,定义如下:
c
typedef struct
{
uint32_t HRTIMInterruptResquests;
uint32_t SyncOptions;
uint32_t SyncInputSource;
uint32_t SyncOutputSource;
uint32_t SyncOutputPolarity;
} HRTIM_InitTypeDef;
各成员参数说明:
HRTIMInterruptResquests:全局中断请求使能配置,可选参数:
c
#define HRTIM_IT_NONE 0x00000000U /*!< No interrupt enabled */
#define HRTIM_IT_FLT1 HRTIM_IER_FLT1 /*!< Fault 1 interrupt enable */
#define HRTIM_IT_FLT2 HRTIM_IER_FLT2 /*!< Fault 2 interrupt enable */
#define HRTIM_IT_FLT3 HRTIM_IER_FLT3 /*!< Fault 3 interrupt enable */
#define HRTIM_IT_FLT4 HRTIM_IER_FLT4 /*!< Fault 4 interrupt enable */
#define HRTIM_IT_FLT5 HRTIM_IER_FLT5 /*!< Fault 5 interrupt enable */
#define HRTIM_IT_SYSFLT HRTIM_IER_SYSFLT /*!< System Fault interrupt enable */
#define HRTIM_IT_BMPER HRTIM_IER_BMPER /*!< Burst mode period interrupt enable */
SyncOptions:同步模式配置,配置外设为主设备输出同步信号或从设备接收同步信号:
c
#define HRTIM_SYNCOPTION_NONE 0x00000000U
#define HRTIM_SYNCOPTION_MASTER 0x00000001U /*!< Operate as master, output sync pulse via SYNCOUT */
#define HRTIM_SYNCOPTION_SLAVE 0x00000002U /*!< Operate as slave, receive sync pulse via SYNCIN */
SyncInputSource:同步输入源选择,仅从设备模式生效:
c
#define HRTIM_SYNCINPUTSOURCE_NONE 0x00000000U
#define HRTIM_SYNCINPUTSOURCE_INTERNALEVENT HRTIM_MCR_SYNC_IN_1 /*!< Sync source: on-chip TIM peripheral */
#define HRTIM_SYNCINPUTSOURCE_EXTERNALEVENT (HRTIM_MCR_SYNC_IN_1 | HRTIM_MCR_SYNC_IN_0) /*!< Sync source: external SYNCIN pin */
SyncOutputSource:同步脉冲输出触发源,仅主设备模式生效:
c
#define HRTIM_SYNCOUTPUTSOURCE_MASTER_START 0x00000000U /*!< Pulse on master counter start event */
#define HRTIM_SYNCOUTPUTSOURCE_MASTER_CMP1 (HRTIM_MCR_SYNC_SRC_0) /*!< Pulse on master compare 1 event */
#define HRTIM_SYNCOUTPUTSOURCE_TIMA_START (HRTIM_MCR_SYNC_SRC_1) /*!< Pulse on Timer A start / reset event */
#define HRTIM_SYNCOUTPUTSOURCE_TIMA_CMP1 (HRTIM_MCR_SYNC_SRC_1 | HRTIM_MCR_SYNC_SRC_0) /*!< Pulse on Timer A compare 1 event */
SyncOutputPolarity:同步输出脉冲极性配置:
c
#define HRTIM_SYNCOUTPUTPOLARITY_NONE 0x00000000U /*!< Sync output disabled */
#define HRTIM_SYNCOUTPUTPOLARITY_POSITIVE (HRTIM_MCR_SYNC_OUT_1) /*!< Idle low, output 16-cycle positive pulse */
#define HRTIM_SYNCOUTPUTPOLARITY_NEGATIVE (HRTIM_MCR_SYNC_OUT_1 | HRTIM_MCR_SYNC_OUT_0) /*!< Idle high, output 16-cycle negative pulse */
3.3 单元基础参数结构体 HRTIM_TimerParamTypeDef
用于配置单路定时单元捕获触发、DMA、中断基础参数:
c
typedef struct
{
uint32_t CaptureTrigger1;
uint32_t CaptureTrigger2;
uint32_t InterruptRequests;
uint32_t DMARequests;
uint32_t DMASrcAddress;
uint32_t DMADstAddress;
uint32_t DMASize;
} HRTIM_TimerParamTypeDef;
CaptureTrigger1:捕获通道1触发源,分两种工作模式参数集:- Simple Mode 外部事件索引:
c
#define HRTIM_EVENT_NONE (0x00000000U) /*!< Undefined event channel */
#define HRTIM_EVENT_1 (0x00000001U) /*!< External event channel 1 */
#define HRTIM_EVENT_2 (0x00000002U) /*!< External event channel 2 */
#define HRTIM_EVENT_3 (0x00000003U) /*!< External event channel 3 */
#define HRTIM_EVENT_4 (0x00000004U) /*!< External event channel 4 */
#define HRTIM_EVENT_5 (0x00000005U) /*!< External event channel 5 */
#define HRTIM_EVENT_6 (0x00000006U) /*!< External event channel 6 */
#define HRTIM_EVENT_7 (0x00000007U) /*!< External event channel 7 */
#define HRTIM_EVENT_8 (0x00000008U) /*!< External event channel 8 */
#define HRTIM_EVENT_9 (0x00000009U) /*!< External event channel 9 */
#define HRTIM_EVENT_10 (0x0000000AU) /*!< External event channel 10 */
- Waveform Mode 全功能触发源,包含计数器更新、全部外部事件、各单元输出置复位、比较事件;
CaptureTrigger2:捕获通道2触发源,可选参数与CaptureTrigger1完全一致;InterruptRequests:单元内部中断请求使能;DMARequests:单元DMA传输请求使能;DMASrcAddress:DMA传输源地址;DMADstAddress:DMA传输目标地址;DMASize:单次DMA传输数据长度。
3.4 时基配置结构体 HRTIM_TimeBaseCfgTypeDef
配置定时单元计数周期、分频、重复计数、工作模式:
c
typedef struct
{
uint32_t Period;
uint32_t RepetitionCounter;
uint32_t PrescalerRatio;
uint32_t Mode;
} HRTIM_TimeBaseCfgTypeDef;
Period:计数周期计数值,取值下限 3 3 3 个 HRTIM 内核时钟周期,取值上限 0 xFFDF 0\text{xFFDF} 0xFFDF;RepetitionCounter:重复计数寄存器,取值范围 0 x 00 ∼ 0 xFF 0\text{x}00 \sim 0\text{xFF} 0x00∼0xFF;PrescalerRatio:时钟分频/倍频配置;STM32H7 仅支持分频模式(后三项宏):
c
#define HRTIM_PRESCALERRATIO_MUL32 (0x00000000U)
#define HRTIM_PRESCALERRATIO_MUL16 (0x00000001U)
#define HRTIM_PRESCALERRATIO_MUL8 (0x00000002U)
#define HRTIM_PRESCALERRATIO_MUL4 (0x00000003U)
#define HRTIM_PRESCALERRATIO_MUL2 (0x00000004U)
/* STM32H7 supported options */
#define HRTIM_PRESCALERRATIO_DIV1 (0x00000005U)
#define HRTIM_PRESCALERRATIO_DIV2 (0x00000006U)
#define HRTIM_PRESCALERRATIO_DIV4 (0x00000007U)
Mode:计数运行模式:
c
#define HRTIM_MODE_CONTINUOUS (0x00000008U) /*!< Continuous counting mode */
#define HRTIM_MODE_SINGLESHOT (0x00000000U) /*!< Single shot mode, no retrigger */
#define HRTIM_MODE_SINGLESHOT_RETRIGGERABLE (0x00000010U) /*!< Retriggerable single shot mode */
3.5 单元功能配置结构体 HRTIM_TimerCfgTypeDef
覆盖主定时单元、子定时单元全部功能开关,分为全局通用参数、子单元专属参数两类:
c
typedef struct
{
/* Global parameters for master & Timer A ~ E */
uint32_t InterruptRequests;
uint32_t DMARequests;
uint32_t DMASrcAddress;
uint32_t DMADstAddress;
uint32_t DMASize;
uint32_t HalfModeEnable;
uint32_t StartOnSync;
uint32_t ResetOnSync;
uint32_t DACSynchro;
uint32_t PreloadEnable;
uint32_t UpdateGating;
uint32_t BurstMode;
uint32_t RepetitionUpdate;
/* Exclusive parameters for Timer A ~ E only */
uint32_t PushPull;
uint32_t FaultEnable;
uint32_t FaultLock;
uint32_t DeadTimeInsertion;
uint32_t DelayedProtectionMode;
uint32_t UpdateTrigger;
uint32_t ResetTrigger;
uint32_t ResetUpdate;
} HRTIM_TimerCfgTypeDef;
各成员配置说明省略冗余宏定义,功能包含中断/DMA 使能、半周期模式、同步启停复位、DAC 同步、影子寄存器预加载、突发模式行为、故障保护、死区插入、延时保护、寄存器更新触发源配置。
3.6 输出通道配置结构体 HRTIM_OutputCfgTypeDef
单路输出通道电气特性与波形触发规则配置:
c
typedef struct
{
uint32_t Polarity;
uint32_t SetSource;
uint32_t ResetSource;
uint32_t IdleMode;
uint32_t IdleLevel;
uint32_t FaultLevel;
uint32_t ChopperModeEnable;
uint32_t BurstModeEntryDelayed;
} HRTIM_OutputCfgTypeDef;
参数覆盖输出电平极性、置位/复位事件源、突发模式空闲状态、故障安全电平、载波斩波模式、突发模式切换延时配置。
3.7 比较单元配置结构体 HRTIM_CompareCfgTypeDef
配置4组比较寄存器阈值与自动延时功能:
c
typedef struct
{
uint32_t CompareValue;
uint32_t AutoDelayedMode;
uint32_t AutoDelayedTimeout;
} HRTIM_CompareCfgTypeDef;
CompareValue:比较阈值,取值下限 3 3 3 个 HRTIM 时钟周期,取值上限 0 xFFFF − 1 0\text{xFFFF}-1 0xFFFF−1;AutoDelayedMode:仅 CMP2、CMP4 支持自动延时模式;AutoDelayedTimeout:延时参考阈值,约束条件 CompareValue + AutoDelayedTimeout ≤ 0 xFFFFU \text{CompareValue} + \text{AutoDelayedTimeout} \le 0\text{xFFFFU} CompareValue+AutoDelayedTimeout≤0xFFFFU。
3.8 外设句柄结构体 HRTIM_HandleTypeDef
HAL 库顶层句柄,整合寄存器基地址、全部配置结构体、DMA 句柄、状态锁、回调函数指针:
c
#if (USE_HAL_HRTIM_REGISTER_CALLBACKS == 1)
typedef struct __HRTIM_HandleTypeDef
#else
typedef struct
#endif
{
HRTIM_TypeDef * Instance; /*!< Register base address */
HRTIM_InitTypeDef Init; /*!< Global HRTIM configuration */
HRTIM_TimerParamTypeDef TimerParam[MAX_HRTIM_TIMER]; /*!< Per-timer parameter storage */
HAL_LockTypeDef Lock; /*!< Resource lock object */
__IO HAL_HRTIM_StateTypeDef State; /*!< Peripheral running state */
DMA_HandleTypeDef * hdmaMaster; /*!< Master timer DMA handle */
DMA_HandleTypeDef * hdmaTimerA; /*!< Timer A DMA handle */
DMA_HandleTypeDef * hdmaTimerB; /*!< Timer B DMA handle */
DMA_HandleTypeDef * hdmaTimerC; /*!< Timer C DMA handle */
DMA_HandleTypeDef * hdmaTimerD; /*!< Timer D DMA handle */
DMA_HandleTypeDef * hdmaTimerE; /*!< Timer E DMA handle */
#if (USE_HAL_HRTIM_REGISTER_CALLBACKS == 1)
/* Global fault & system callbacks */
void (* Fault1Callback)(struct __HRTIM_HandleTypeDef *hhrtim);
void (* Fault2Callback)(struct __HRTIM_HandleTypeDef *hhrtim);
void (* Fault3Callback)(struct __HRTIM_HandleTypeDef *hhrtim);
void (* Fault4Callback)(struct __HRTIM_HandleTypeDef *hhrtim);
void (* Fault5Callback)(struct __HRTIM_HandleTypeDef *hhrtim);
void (* SystemFaultCallback)(struct __HRTIM_HandleTypeDef *hhrtim);
void (* BurstModePeriodCallback)(struct __HRTIM_HandleTypeDef *hhrtim);
void (* SynchronizationEventCallback)(struct __HRTIM_HandleTypeDef *hhrtim);
void (* ErrorCallback)(struct __HRTIM_HandleTypeDef *hhrtim);
/* Per-timer event callbacks */
void (* RegistersUpdateCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx);
void (* RepetitionEventCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx);
void (* Compare1EventCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx);
void (* Compare2EventCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx);
void (* Compare3EventCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx);
void (* Compare4EventCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx);
void (* Capture1EventCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx);
void (* Capture2EventCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx);
void (* DelayedProtectionCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx);
void (* CounterResetCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx);
void (* Output1SetCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx);
void (* Output1ResetCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx);
void (* Output2SetCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx);
void (* Output2ResetCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx);
void (* BurstDMATransferCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx);
/* Low level hardware init callbacks */
void (* MspInitCallback)(struct __HRTIM_HandleTypeDef *hhrtim);
void (* MspDeInitCallback)(struct __HRTIM_HandleTypeDef *hhrtim);
#endif
} HRTIM_HandleTypeDef;
宏 USE_HAL_HRTIM_REGISTER_CALLBACKS 定义于 stm32h7xx_hal_conf.h,置1时支持动态注册独立回调函数,各定时单元可绑定专属事件处理逻辑。
3.9 底层硬件初始化回调 MspInit / MspDeInit
函数 HAL_HRTIM_Init 内部调用弱定义底层初始化函数 HAL_HRTIM_MspInit,用于配置外设时钟、GPIO 复用、中断优先级、DMA 底层资源:
c
__weak void HAL_HRTIM_MspInit(HRTIM_HandleTypeDef * hhrtim)
{
UNUSED(hhrtim);
/* User hardware initialization implementation here */
}
复位配套回调函数 HAL_HRTIM_MspDeInit 同样为弱定义,用户可在工程文件重写函数实现自定义底层逻辑。
启用动态回调宏 USE_HAL_HRTIM_REGISTER_CALLBACKS = 1 后,可通过 HAL_HRTIM_RegisterCallback 绑定自定义 Msp 回调,实现多实例独立底层配置。
HRTIM 输出引脚复用配置宏定义(stm32h7xx_hal_gpio_ex.h),外设复用编号分为 AF1 / AF2 / AF3:
c
#define GPIO_AF1_HRTIM1 ((uint8_t)0x01)
#define GPIO_AF2_HRTIM1 ((uint8_t)0x02)
#define GPIO_AF3_HRTIM1 ((uint8_t)0x03)
引脚复用编号需对照芯片数据手册引脚分配表选择。
3.10 HAL 库标准开发流程
HRTIM HAL 接口分为两类工作模式:Simple Mode、Waveform Mode。
- Simple Mode:功能子集,与通用 TIM 逻辑兼容,仅支持基础输出比较、PWM、输入捕获、单脉冲;接口命名前缀
HAL_HRTIM_Simple。 - Waveform Mode:全功能模式,启用外设全部硬件逻辑;接口命名前缀
HAL_HRTIM_Waveform。
步骤1 底层硬件初始化(MspInit)
- 调用
__HRTIMx_CLK_ENABLE()开启外设时钟; - 开启对应 GPIO 端口时钟,调用
HAL_GPIO_Init配置引脚复用; - DMA 传输场景额外配置:DMA 时钟开启、DMA 句柄初始化、
__HAL_LINKDMA绑定外设与 DMA、HAL_DMA_Init、NVIC 中断优先级与使能; - 中断传输场景配置 NVIC 中断优先级、中断使能。
步骤2 全局外设初始化 HAL_HRTIM_Init
完成全局同步模式、全局中断配置,绑定底层 Msp 回调。
步骤3 外设全局功能配置
- 突发模式控制器:
HAL_HRTIM_BurstModeConfig - 外部事件参数:
HAL_HRTIM_EventConfig、HAL_HRTIM_EventPrescalerConfig - 故障保护通道:
HAL_HRTIM_FaultConfig、HAL_HRTIM_FaultPrescalerConfig、HAL_HRTIM_FaultModeCtl - ADC 硬件触发:
HAL_HRTIM_ADCTriggerConfig
步骤4 时基单元配置
调用 HAL_HRTIM_TimeBaseConfig,Simple / Waveform 模式均必须执行;配置计数模式、分频、周期、重复计数器。
步骤5 Simple Mode 专用接口调用
包含时基启停、输出比较、PWM、输入捕获、单脉冲全套阻塞/中断/DMA 接口。
步骤6 Waveform Mode 全功能接口调用
接口:HAL_HRTIM_WaveformTimerConfig、死区配置、斩波载波、DMA 突发、比较/捕获/输出通道配置、输出使能、计数器启停、软件触发接口。
步骤7 动态回调注册(可选)
- 头文件开启
USE_HAL_HRTIM_REGISTER_CALLBACKS = 1; - 调用
HAL_HRTIM_RegisterCallback/HAL_HRTIM_TIMxRegisterCallback绑定各类事件回调; - 注销使用
HAL_HRTIM_UnRegisterCallback/HAL_HRTIM_TIMxUnRegisterCallback; - 回调注册约束:仅外设状态为
HAL_HRTIM_STATE_READY允许注册/注销,Msp 回调支持HAL_HRTIM_STATE_RESET状态操作。
4 底层驱动文件 stm32h7xx_hal_hrtim.c 接口说明
本节解析工程高频调用函数原型、参数、使用约束与示例。
4.1 HAL_HRTIM_Init
函数原型
c
HAL_StatusTypeDef HAL_HRTIM_Init(HRTIM_HandleTypeDef * hhrtim)
功能描述
完成 HRTIM 全局寄存器初始化、同步输入/输出配置、底层硬件回调绑定、句柄状态初始化。
入参
hhrtim:HRTIM 外设句柄指针;
返回值
HAL_OK:配置完成;HAL_ERROR:入参非法;HAL_BUSY:外设占用;HAL_TIMEOUT:操作超时。
使用约束
- 局部句柄变量需预先清零或调用
HAL_HRTIM_DeInit复位,避免随机状态导致配置异常; - 动态回调宏开启后,自动填充默认弱定义回调指针,用户注册自定义回调后覆盖默认逻辑。
4.2 HAL_HRTIM_TimeBaseConfig
函数原型
c
HAL_StatusTypeDef HAL_HRTIM_TimeBaseConfig(HRTIM_HandleTypeDef *hhrtim,
uint32_t TimerIdx,
HRTIM_TimeBaseCfgTypeDef * pTimeBaseCfg)
功能描述
配置指定定时单元计数时基参数,主单元、子单元通用。
入参
hhrtim:外设句柄;TimerIdx:定时单元索引(Master / TIMA ~ TIME);pTimeBaseCfg:时基配置结构体指针;
使用约束
计数器启动前必须调用该函数,配置分频、周期、重复计数、连续/单次模式。
4.3 HAL_HRTIM_WaveformTimerConfig
函数原型
c
HAL_StatusTypeDef HAL_HRTIM_WaveformTimerConfig(HRTIM_HandleTypeDef * hhrtim,
uint32_t TimerIdx,
HRTIM_TimerCfgTypeDef * pTimerCfg)
功能描述
Waveform 模式单元功能总配置,包含中断/DMA、同步逻辑、死区、故障保护、寄存器更新规则。
使用约束
仅 Waveform 模式生效,计数器启动前完成配置。
4.4 HAL_HRTIM_WaveformCompareConfig
函数原型
c
HAL_StatusTypeDef HAL_HRTIM_WaveformCompareConfig(HRTIM_HandleTypeDef * hhrtim,
uint32_t TimerIdx,
uint32_t CompareUnit,
HRTIM_CompareCfgTypeDef* pCompareCfg)
功能描述
配置单组比较寄存器阈值与自动延时参数;
使用约束
CMP2 / CMP4 启用自动延时模式时,必须配套配置对应捕获通道。
4.5 HAL_HRTIM_WaveformOutputConfig
函数原型
c
HAL_StatusTypeDef HAL_HRTIM_WaveformOutputConfig(HRTIM_HandleTypeDef * hhrtim,
uint32_t TimerIdx,
uint32_t Output,
HRTIM_OutputCfgTypeDef * pOutputCfg)
功能描述
配置单路输出通道极性、置复位源、故障电平、空闲模式;
使用约束
死区插入配置前执行本函数。
4.6 HAL_HRTIM_WaveformOutputStart
函数原型
c
HAL_StatusTypeDef HAL_HRTIM_WaveformOutputStart(HRTIM_HandleTypeDef * hhrtim,
uint32_t OutputsToStart)
功能描述
使能指定输出通道,多通道支持按位或组合入参。
4.7 HAL_HRTIM_WaveformCountStart(别名 HAL_HRTIM_WaveformCounterStart)
函数原型
c
#define HAL_HRTIM_WaveformCounterStart HAL_HRTIM_WaveformCountStart
HAL_StatusTypeDef HAL_HRTIM_WaveformCountStart(HRTIM_HandleTypeDef * hhrtim,
uint32_t Timers)
功能描述
启动指定定时单元计数器,支持多单元按位或同步启动。
5 总结
本文完整阐述 STM32H7 HRTIM 硬件架构、时序分辨率、波形生成逻辑与全套 HAL 库结构体、标准调用流程、驱动接口。工程开发可结合芯片参考手册补充寄存器细节,完善多路同步、故障保护、DMA 动态更新 PWM 等复杂应用。
【STM32】CubeMX+HAL 库 HRTIM 多路同步独立定时器 DMA 动态更新比较阈值
A.大畅哥
2021-09-19 12:55:12
前言
对比通用 TIM 外设,HRTIM 优势为时钟倍频能力,在高频工作条件下仍可维持纳秒级时序精度;典型应用包含数字电源、照明驱动、光伏逆变器、无线充电装置,同时兼容通用定时功能。
开发环境
- 硬件平台:STM32G474RE 开发板
- 配置工具:STM32CubeMX
- 编译环境:Keil-MDK
硬件基础特性
主定时单元 Master Timer
16 bit 递增计数器架构,内置4组比较寄存器控制全部输出通道置位/复位,向 Timer A ~ Timer F 输出全局同步基准;多路交错式 Buck-Boost 电源拓扑为典型应用,通过主单元完成多路输出移相控制。
子定时单元 Timer A ~ Timer F
支持独立运行或多单元联动;每路单元驱动两路输出通道,置/复位触发源包含内部比较寄存器、主单元事件、其余子单元事件、外部硬件事件;两路输出配套能力:
- 互补 PWM 波形输出,硬件死区插入;
- 输出叠加高频载波信号;
- 故障触发时异步强制输出预设安全电平。
外部事件输入
10 路外部事件通道,可接入任意定时单元;支持极性、有效边沿可编程;5 路高速异步通道、5 路带数字滤波通道;消隐区间、窗口检测电路过滤干扰脉冲。
模拟外设触发链路
4 路 ADC 转换触发、3 路 DAC 更新触发、3 路片内比较器事件捕获。
硬件保护机制
5 路故障输入支持逻辑组合,可绑定任意定时单元;极性、检测边沿可配置;谐振变换器专用延时保护电路。
多芯片时序同步
不同器件 HRTIM 可通过同步输入/输出引脚实现全局时序对齐。
STM32CubeMX HRTIM 图形化配置流程
1 系统时钟配置
时钟配置参考文档:https://blog.csdn.net/weixin_45065888/article/details/115789200?spm=1001.2014.3001.5502
配套时钟配置截图:

2 HRTIM 外设参数配置
-
启用主定时单元,选择目标子定时单元
-
主单元分频/倍频、周期计数值配置,设置输出频率
-
开启影子寄存器预加载、重复计数更新、全局中断

-
子定时单元通用配置:分频/倍频、周期计数值
-
启用预加载、重复更新;互补输出场景配置死区时长,单路独立输出死区参数置0;开启比较寄存器 DMA 传输请求
-
死区沿选择、输出有效电平、置/复位触发源配置

- 开启 DMA 外设通道

- 多路单元同步配置:指定主定时单元作为全局同步源,复位信号同步全部子单元

完成全部参数配置后生成工程代码。
工程代码实现
初始化执行代码
c
// 启动主定时单元计数(中断模式)
HAL_HRTIM_WaveformCounterStart_IT(&hhrtim1, HRTIM_TIMERID_MASTER);
// 直接写入比较寄存器阈值
__HAL_HRTIM_SETCOMPARE(&hhrtim1, HRTIM_TIMERINDEX_TIMER_B, HRTIM_COMPAREUNIT_1, (uint32_t)HRTIM_DMA_Buffer[0]);
__HAL_HRTIM_SETCOMPARE(&hhrtim1, HRTIM_TIMERINDEX_TIMER_E, HRTIM_COMPAREUNIT_2, (uint32_t)HRTIM_DMA_Buffer[1]);
// 使能 Timer B 两路输出通道
HAL_HRTIM_WaveformOutputStart(&hhrtim1, HRTIM_OUTPUT_TB1 + HRTIM_OUTPUT_TB2);
// Timer B 计数器启动,DMA 动态刷新比较值
HAL_HRTIM_WaveformCounterStart_DMA(&hhrtim1, HRTIM_TIMERID_TIMER_B);
// 使能 Timer E 两路输出通道
HAL_HRTIM_WaveformOutputStart(&hhrtim1, HRTIM_OUTPUT_TE1 + HRTIM_OUTPUT_TE2);
// Timer E 计数器启动,DMA 动态刷新比较值
HAL_HRTIM_WaveformCounterStart_DMA(&hhrtim1, HRTIM_TIMERID_TIMER_E);
主定时单元重复计数中断回调(动态更新DMA缓冲区)
c
void HAL_HRTIM_RepetitionEventCallback(HRTIM_HandleTypeDef * hhrtim, uint32_t TimerIdx)
{
// 动态计算新占空比对应的比较阈值
HRTIM_DMA_Buffer[0] = 13600U;
HRTIM_DMA_Buffer[1] = 13600U;
}
STM32G474 单片机开发入门 - HRTIM 高精度定时器 50 kHz PWM 输出工程实践
光子物联单片机
2025-10-25 13:35:30
一、内容概述
前文《STM32G474 单片机开发入门 (七) 定时器 PWM 波输出与输入实战》采用通用 TIM2_CH4 实现脉冲宽度调制输出。STM32G4 系列集成专属高精度定时器外设 HRTIM,本节介绍外设硬件特性,并给出 50 kHz PWM 波形输出完整工程实现方案。

二、HRTIM 硬件特性
-
超高时序分辨率
外设内核基准时钟为 170 MHz 170 \ \text{MHz} 170 MHz,支持 32 倍倍频,内核运行时钟可达 5.44 GHz 5.44 \ \text{GHz} 5.44 GHz,最小时序步长 184 ps 184 \ \text{ps} 184 ps,可高精度调节 PWM 频率与占空比。通用定时器 TIM1 / TIM2 无倍频机制,时序分辨率仅纳秒级,时序控制精度低于 HRTIM。HRTIM 内部计数单元内置电压、温度漂移补偿电路,长时间运行时序稳定性满足开关电源需求。
-
多通道模块化控制架构
包含 6 路独立 16 bit 子定时单元,每路单元配备 4 组比较寄存器,单路输出通道支持至多 32 组置位/复位触发源。模块化硬件架构适配 Buck、Boost、全桥、谐振等各类开关电源拓扑。
-
集成高级 PWM 硬件功能
硬件原生支持互补 PWM 波形输出与死区时间插入;集成突发模式,可编程切换运行/空闲周期,降低开关器件损耗;支持单脉冲输出、重复计数、多级硬件故障关断保护。
典型应用场景:高频开关电源、电机矢量驱动、逆变设备。该外设参数配置流程复杂度高于通用定时器,需合理配置主定时单元同步事件,避免波形丢失问题。
三、HRTIM 内部硬件框图

外设硬件架构说明:
HRTIM 包含 1 路主定时单元(Master Timer)、6 路子定时单元 Timer A ~ Timer F,7 路定时单元可独立运行或联动同步。
每路子定时单元硬件资源:
- 16 bit 递增计数器
- 4 组 16 bit 比较寄存器
- 2 组 16 bit 捕获寄存器
- 2 路独立 PWM 输出通道
主定时单元由 5.44 GHz 5.44 \ \text{GHz} 5.44 GHz 内核时钟驱动,提供 184 ps 184 \ \text{ps} 184 ps 时序分辨率;主单元无物理输出引脚,子定时单元可通过片内总线接收主单元同步事件(计数器启动、复位、更新)。
四、STM32CubeMX 配置 HRTIM1 输出 50 kHz PWM 工程示例
4.1 硬件测试平台
调试工具:STLINK 下载器,连接 PC USB 接口;
测量设备:示波器探头接入 PB14 引脚(HRTIM1_CHD1)观测波形。

4.2 CubeMX 工程创建与参数配置
- 新建工程
打开 STM32CubeMX,新建芯片工程。
器件型号输入 STM32G474RE,双击器件完成工程创建。
-
调试引脚配置
配置 PA13 为 SWDIO、PA14 为 SWCLK,启用串行下载接口。
-
HRTIM 外设引脚与时序参数配置
配置 HRTIM1,输出频率 50 kHz 50 \ \text{kHz} 50 kHz、占空比 50 % 50\% 50%,PB14 复用为 HRTIM1_CHD1 输出引脚。
-
系统时钟树配置
外部 8 MHz 8 \ \text{MHz} 8 MHz 晶振输入,系统主频配置为 170 MHz 170 \ \text{MHz} 170 MHz。
-
工程输出配置
设置工程存储路径、工程名称,输出 Keil MDK-ARM 工程文件。

- 用户代码补充说明
工程生成后添加波形启动调用代码:
定义周期计算宏,倍频系数根据目标频率调整;低频场景需降低倍频倍率。
4.3 完整工程源码
c
#define HRTIM_INPUT_CLOCK 170000000U
#define TIMD_PWM_FREQ 50000U
#define TIMD_DUTY_CYCLE 0.5F
// 周期计数值计算公式
// 100 kHz PWM 适配倍频MUL32:#define TIMD_PERIOD ((uint16_t)((((uint64_t)HRTIM_INPUT_CLOCK) * 32) / TIMD_PWM_FREQ))
#define TIMD_PERIOD ((uint16_t)((((uint64_t)HRTIM_INPUT_CLOCK) * 16) / TIMD_PWM_FREQ))
/* 倍频/分频参数说明 */
//#define HRTIM_PRESCALERRATIO_MUL32 (0x00000000U) /* fHRCK = fHRTIM × 32 = 4.608 GHz, Resolution: 217 ps, Min PWM frequency: 70.3 kHz (fHRTIM=144 MHz) */
//#define HRTIM_PRESCALERRATIO_MUL16 (0x00000001U) /* fHRCK = fHRTIM × 16 = 2.304 GHz, Resolution: 434 ps, Min PWM frequency: 35.1 kHz (fHRTIM=144 MHz) */
//#define HRTIM_PRESCALERRATIO_MUL8 (0x00000002U) /* fHRCK = fHRTIM × 8 = 1.152 GHz, Resolution: 868 ps, Min PWM frequency: 17.6 kHz (fHRTIM=144 MHz) */
//#define HRTIM_PRESCALERRATIO_MUL4 (0x00000003U) /* fHRCK = fHRTIM × 4 = 576 MHz, Resolution: 1.73 ns, Min PWM frequency: 8.8 kHz (fHRTIM=144 MHz) */
//#define HRTIM_PRESCALERRATIO_MUL2 (0x00000004U) /* fHRCK = fHRTIM × 2 = 288 MHz, Resolution: 3.47 ns, Min PWM frequency: 4.4 kHz (fHRTIM=144 MHz) */
//#define HRTIM_PRESCALERRATIO_DIV1 (0x00000005U) /* fHRCK = fHRTIM = 144 MHz, Resolution: 6.95 ns, Min PWM frequency: 2.2 kHz (fHRTIM=144 MHz) */
//#define HRTIM_PRESCALERRATIO_DIV2 (0x00000006U) /* fHRCK = fHRTIM / 2 = 72 MHz, Resolution: 13.88 ns, Min PWM frequency: 1.1 kHz (fHRTIM=144 MHz) */
//#define HRTIM_PRESCALERRATIO_DIV4 (0x00000007U) /* fHRCK = fHRTIM / 4 = 36 MHz, Resolution: 27.7 ns, Min PWM frequency: 550 Hz (fHRTIM=144 MHz) */
/* USER CODE END 0 */
HRTIM_HandleTypeDef hhrtim1;
void MX_HRTIM1_Init(void)
{
HRTIM_TimeBaseCfgTypeDef pTimeBaseCfg = {0};
HRTIM_TimerCtlTypeDef pTimerCtl = {0};
HRTIM_TimerCfgTypeDef pTimerCfg = {0};
HRTIM_CompareCfgTypeDef pCompareCfg = {0};
HRTIM_OutputCfgTypeDef pOutputCfg = {0};
hhrtim1.Instance = HRTIM1;
hhrtim1.Init.HRTIMInterruptResquests = HRTIM_IT_NONE;
hhrtim1.Init.SyncOptions = HRTIM_SYNCOPTION_NONE;
if (HAL_HRTIM_Init(&hhrtim1) != HAL_OK)
{
Error_Handler();
}
// DLL 时序校准
if (HAL_HRTIM_DLLCalibrationStart(&hhrtim1, HRTIM_CALIBRATIONRATE_3) != HAL_OK)
{
Error_Handler();
}
if (HAL_HRTIM_PollForDLLCalibration(&hhrtim1, 10) != HAL_OK)
{
Error_Handler();
}
// 时基配置
pTimeBaseCfg.Period = TIMD_PERIOD;
pTimeBaseCfg.RepetitionCounter = 0x00U;
pTimeBaseCfg.PrescalerRatio = HRTIM_PRESCALERRATIO_MUL16;
pTimeBaseCfg.Mode = HRTIM_MODE_CONTINUOUS;
if (HAL_HRTIM_TimeBaseConfig(&hhrtim1, HRTIM_TIMERINDEX_TIMER_D, &pTimeBaseCfg) != HAL_OK)
{
Error_Handler();
}
// 计数控制配置
pTimerCtl.UpDownMode = HRTIM_TIMERUPDOWNMODE_UP;
pTimerCtl.GreaterCMP1 = HRTIM_TIMERGTCMP1_EQUAL;
pTimerCtl.DualChannelDacEnable = HRTIM_TIMER_DCDE_DISABLED;
if (HAL_HRTIM_WaveformTimerControl(&hhrtim1, HRTIM_TIMERINDEX_TIMER_D, &pTimerCtl) != HAL_OK)
{
Error_Handler();
}
// 单元功能配置
pTimerCfg.InterruptRequests = HRTIM_TIM_IT_NONE;
pTimerCfg.DMARequests = HRTIM_TIM_DMA_NONE;
pTimerCfg.DMASrcAddress = 0x0000U;
pTimerCfg.DMADstAddress = 0x0000U;
pTimerCfg.DMASize = 0x1U;
pTimerCfg.HalfModeEnable = HRTIM_HALFMODE_DISABLED;
pTimerCfg.InterleavedMode = HRTIM_INTERLEAVED_MODE_DISABLED;
pTimerCfg.StartOnSync = HRTIM_SYNCSTART_DISABLED;
pTimerCfg.ResetOnSync = HRTIM_SYNCRESET_DISABLED;
pTimerCfg.DACSynchro = HRTIM_DACSYNC_NONE;
pTimerCfg.PreloadEnable = HRTIM_PRELOAD_DISABLED;
pTimerCfg.UpdateGating = HRTIM_UPDATEGATING_INDEPENDENT;
pTimerCfg.BurstMode = HRTIM_TIMERBURSTMODE_MAINTAINCLOCK;
pTimerCfg.RepetitionUpdate = HRTIM_UPDATEONREPETITION_DISABLED;
pTimerCfg.PushPull = HRTIM_TIMPUSHPULLMODE_DISABLED;
pTimerCfg.FaultEnable = HRTIM_TIMFAULTENABLE_NONE;
pTimerCfg.FaultLock = HRTIM_TIMFAULTLOCK_READWRITE;
pTimerCfg.DeadTimeInsertion = HRTIM_TIMDEADTIMEINSERTION_DISABLED;
pTimerCfg.DelayedProtectionMode = HRTIM_TIMER_D_E_DELAYEDPROTECTION_DISABLED;
pTimerCfg.UpdateTrigger = HRTIM_TIMUPDATETRIGGER_NONE;
pTimerCfg.ResetTrigger = HRTIM_TIMRESETTRIGGER_NONE;
pTimerCfg.ResetUpdate = HRTIM_TIMUPDATEONRESET_DISABLED;
pTimerCfg.ReSyncUpdate = HRTIM_TIMERESYNC_UPDATE_UNCONDITIONAL;
if (HAL_HRTIM_WaveformTimerConfig(&hhrtim1, HRTIM_TIMERINDEX_TIMER_D, &pTimerCfg) != HAL_OK)
{
Error_Handler();
}
// 比较阈值配置
pCompareCfg.CompareValue = (uint16_t)((float)TIMD_PERIOD * TIMD_DUTY_CYCLE);
if (HAL_HRTIM_WaveformCompareConfig(&hhrtim1, HRTIM_TIMERINDEX_TIMER_D, HRTIM_COMPAREUNIT_1, &pCompareCfg) != HAL_OK)
{
Error_Handler();
}
// 输出通道配置
pOutputCfg.Polarity = HRTIM_OUTPUTPOLARITY_HIGH;
pOutputCfg.SetSource = HRTIM_OUTPUTSET_TIMPER;
pOutputCfg.ResetSource = HRTIM_OUTPUTRESET_TIMCMP1;
pOutputCfg.IdleMode = HRTIM_OUTPUTIDLEMODE_NONE;
pOutputCfg.IdleLevel = HRTIM_OUTPUTIDLELEVEL_INACTIVE;
pOutputCfg.FaultLevel = HRTIM_OUTPUTFAULTLEVEL_NONE;
pOutputCfg.ChopperModeEnable = HRTIM_OUTPUTCHOPPERMODE_DISABLED;
pOutputCfg.BurstModeEntryDelayed = HRTIM_OUTPUTBURSTMODEENTRY_REGULAR;
if (HAL_HRTIM_WaveformOutputConfig(&hhrtim1, HRTIM_TIMERINDEX_TIMER_D, HRTIM_OUTPUT_TD1, &pOutputCfg) != HAL_OK)
{
Error_Handler();
}
HAL_HRTIM_MspPostInit(&hhrtim1);
}
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
// MCU 基础初始化
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
// 系统时钟配置(外部8 MHz晶振,主频170 MHz)
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
// 外设初始化
MX_GPIO_Init();
MX_HRTIM1_Init();
/* USER CODE BEGIN 2 */
// 启动波形输出通道 TD1
HAL_HRTIM_WaveformOutputStart(&hhrtim1, HRTIM_OUTPUT_TD1);
// 启动 Timer D 计数器
HAL_HRTIM_WaveformCounterStart(&hhrtim1, HRTIM_TIMERID_TIMER_D);
/* USER CODE END 2 */
while (1)
{
/* USER CODE BEGIN WHILE */
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
}
4.4 波形实测结果
示波器连接 PB14 引脚观测输出波形,实测输出频率 50 kHz 50 \ \text{kHz} 50 kHz,占空比 50 % 50\% 50%,波形时序稳定。
五、内容小结
STM32G474RET6 搭载的 HRTIM 外设可实现高精度细分驱动,适配 CNC 机床、3D 打印设备;可完成永磁同步电机磁场定向控制,用于无人机、电动工具驱动;多单元同步架构支持多轴机械臂协同时序控制;在数字电源开发场景具备突出优势, 184 ps 184 \ \text{ps} 184 ps 最小时序步长可完成纳秒级精准时序调控。
皮秒(ps)基础定义与电路应用
一、皮秒的定义与单位换算
1.1 定义
ps 为 picosecond 的缩写,中文译为皮秒 ,是时间单位。
1 ps = 10 − 12 s = 1 1 000 000 000 000 秒 1\ \text{ps} = 10^{-12}\ \text{s} = \frac{1}{1\,000\,000\,000\,000}\ \text{秒} 1 ps=10−12 s=10000000000001 秒
1.2 十进制换算关系(千倍递进)
1 s = 1000 ms(毫秒) 1 ms = 1000 μ s(微秒) 1 μ s = 1000 ns(纳秒) 1 ns = 1000 ps(皮秒) \begin{align*} 1\ \text{s} &= 1000\ \text{ms(毫秒)} \\ 1\ \text{ms} &= 1000\ \mu\text{s(微秒)} \\ 1\ \mu\text{s} &= 1000\ \text{ns(纳秒)} \\ 1\ \text{ns} &= 1000\ \text{ps(皮秒)} \end{align*} 1 s1 ms1 μs1 ns=1000 ms(毫秒)=1000 μs(微秒)=1000 ns(纳秒)=1000 ps(皮秒)
即 1 ns = 1000 ps 1\ \text{ns} = 1000\ \text{ps} 1 ns=1000 ps。
1.3 换算示例
| 皮秒(ps) | 纳秒(ns) |
|---|---|
| 1000 ps | 1 ns |
| 300 ps | 0.3 ns |
| 30 ps | 0.03 ns |
二、"ps 级精度"的含义
2.1 定义
ps 级 指电路能够分辨并调整信号边沿的最小时间刻度达到皮秒量级(几十至几百 ps)。
2.2 普通 MCU 定时器的限制
以系统时钟频率 f = 200 MHz f = 200\ \text{MHz} f=200 MHz 为例,时钟周期为:
T = 1 200 MHz = 5 ns = 5000 ps T = \frac{1}{200\ \text{MHz}} = 5\ \text{ns} = 5000\ \text{ps} T=200 MHz1=5 ns=5000 ps
普通定时器以该时钟周期为最小计时单位,即最小调整步长为 5000 ps,无法实现更精细的时间微调。
2.3 DLL 延迟锁相环细分后的 ps 级效果
在 200 MHz 时钟基础上,通过 16 档延迟细分,单步延时为:
5 ns 16 = 0.3125 ns = 312.5 ps \frac{5\ \text{ns}}{16} = 0.3125\ \text{ns} = 312.5\ \text{ps} 165 ns=0.3125 ns=312.5 ps
此时电路能够以 312.5 ps 为单位调整 PWM 上升沿或下降沿的位置,即达到 300 ps 级 或 ps 级精度。
TDC(时间数字转换器)纯门延迟方案可进一步将分辨率提升至 30 ps,属于更高一档的 ps 级精度。
三、电路中 "ps 级" 的实际含义
3.1 并非计数器运行至 GHz
处理器内核与定时器计数器仍以 200 MHz 等较低频率运行,ps 级精度通过延迟链(Delay Line) 在单个时钟周期内部进行时间细分,从而实现亚纳秒乃至皮秒量级的微调。
3.2 适用场景
| 应用场景 | 说明 |
|---|---|
| HRPWM、HTrim | 高精度 PWM 边沿调整 |
| TDC | 时间数字转换(激光测距、脉冲捕获) |
| 高速串行时序校准 | 高速总线信号对齐 |
| PCB 等长匹配 | 走线延迟补偿 |
3.3 时间尺度直观对比
| 量级 | 典型应用 |
|---|---|
| 微秒( μ \mu μs) | 电机控制、普通串口通信 |
| 纳秒(ns) | CPU 运算、普通 MCU 时钟周期 |
| 皮秒(ps) | 高速 PWM、激光测距、高速总线时序微调 |
四、单片机 ps 级 HTrim 高精度延时 / 高分辨率 PWM 技术
4.1 普通 MCU 定时器计数器无法运行在 GHz 级别频率,如何实现 ps 级边沿精度?
常规定时器计数器只能按系统主时钟周期做步进(如 200 MHz 系统时钟单周期 5 ns),无法直接输出几百 ps 甚至几十 ps 的微调。行业主流方案不提升主计数器运行频率 ,采用时钟周期内模拟 / 逻辑延迟细分,将 1 个系统时钟切分成多等份,实现亚纳秒、皮秒级边沿微调,对应高精度 HRPWM、HTrim、TDC 时间测量。
4.2 四大主流技术路线
4.2.1 DLL(延迟锁相环)方案
DLL 是 MCU 实现 HRPWM / HTrim 最常用的技术路径。
实现逻辑:
- 输入:PLL 生成稳定系统时钟(例 200 MHz,单周期 5 ns);
- 延迟链:片上模拟延迟链生成 16 / 32 路均匀等分延迟抽头(4 bit / 5 bit 细分);
- 等效分辨率 :200 MHz × \times × 16 细分等效 3.2 GHz 时间分辨率,单步延时 ≈ \approx ≈ 312 ps;32 细分等效 6.4 GHz,单步 ≈ \approx ≈ 156 ps;
- 计数分层:主定时器仍以 200 MHz 低速计数,细分不叠加到计数器,仅通过寄存器选择对应延迟抽头调整 PWM 上升 / 下降沿,计数器无需跑高频;
- 集成方式:同 Die 集成,和 MCU 数字逻辑、PLL 共用一套流片工艺,不需要异芯合封。
衍生变种:
DPLL(数字延迟锁相环):数字辅助校准模拟延迟链,降低纯模拟方案对 PVT 的敏感度。
优缺点:
| 维度 | 说明 |
|---|---|
| 优势 | 细分位数高、集成在 MCU 标准工艺、适配 HRPWM 与 TDC 高精度时间捕获 |
| 短板 | 纯模拟延迟链对 PVT(工艺、电压、温度)敏感,漂移会破坏等分精度;模拟 IP 开发周期长,国内厂商通常需多次流片迭代才能达标;模拟电路设计门槛高 |
4.2.2 TI MEP(微边沿定位)技术
- 底层逻辑:与 DLL 同源,在单个系统时钟内做多阶延迟细分提升 PWM 分辨率;
- 差异点:延迟单元结构、数字校准逻辑和 DLL 模拟延迟链实现架构不同,属于 TI 专用 DSP / MCU 外设 IP。
4.2.3 门延迟型 TDC(时间数字转换器)
- 原理:直接利用标准逻辑门传输延迟做超精细细分,无需复杂模拟锁相环;
- 精度上限:可做到 30 ps 级,细分粒度优于传统 DLL;
- 关联:纯逻辑门延迟 TDC 架构和 MEP 底层思路近似,属于全数字细分方案;
- 适用场景:高精度测距、脉冲时间捕获,也可复用做 HTrim 边沿微调。
4.2.4 抖频技术
- 补充细分路径,通过微小时钟频率抖动等效实现平均化亚周期分辨率;
- 相比延迟链方案瞬时精度更低,多用于低成本场景。
4.3 技术路线对比
| 技术 | 原理 | 分辨率 | 特点 | 适用场景 |
|---|---|---|---|---|
| DLL | 模拟延迟链细分 | ~300 ps(16 细分) | 主流方案,模拟设计要求高 | 工业 MCU 标准 HRPWM |
| DPLL | 数字化延迟控制 | ~300 ps | PVT 鲁棒性更好 | DLL 的数字化改进方案 |
| MEP | 逻辑门延迟链 | ~150 ps | TI 专有技术,需校准 | TI DSP / MCU 专用 |
| TDC | 逻辑门延迟测量 | ~30 ps | 全数字,工艺兼容性好 | 超高精度时间捕获 |
| 抖频 | 统计平均 | 等效提升 | 实现简单,频谱扩展 | 低成本 EMI 敏感场景 |
4.4 工艺与主频相关澄清
4.4.1 DLL 细分与芯片最高主频无绑定关系
- CPU / MCU 内核主频、定时器计数器运行频率 ≠ \neq = 延迟链等效细分频率;
- 举例:200 MHz 内核时钟,16 细分等效 3.2 GHz 时间精度,内核计数器依然跑 200 MHz,不存在计数器跑 GHz 的硬件压力;
- 桌面 CPU(45 nm / 32 nm / 22 nm,3 ~ 5 GHz)主频指标不能套用至 MCU DLL 外设,二者电路架构、功耗约束完全不同。
4.4.2 MCU 主流制程与 FPGA 区分
- 通用消费 / 工业 MCU 主流:55 nm / 65 nm / 90 nm / 110 nm,少量厂商导入 40 nm;极少使用 28 nm;
- FPGA(如高云 GW5A,28 nm)可稳定跑 500 MHz 内核主频,仅 FPGA 场景参考,不代表 MCU;
- DLL 模拟 IP 可在 55 ~ 110 nm 成熟 MCU 工艺实现,不强制 28 nm 先进工艺。
4.4.3 内核主频影响因素
同等工艺下,流水线级数越高、Cache / 分支预测 / 总线延迟优化越好,MCU 最高运行主频越高。
4.5 DLL 物理实现原理
4.5.1 翻转流水缓冲器结构
DLL 延迟链的典型实现采用翻转流水缓冲器结构:
- 输入时钟经整形后,高电平触发串联的多个缓冲器;
- 各缓冲器依次翻转,输出端形成相位依次偏移的时钟信号;
- 低电平期间复位缓冲器,为下一周期做准备;
- 每个缓冲器的延迟与主时钟周期相同,通过 16 个缓冲器实现 16 倍时间细分;
- 实际延迟存在工艺偏差,需加入延迟调节电路(如可变负载、电流 starving)进行精确校准。
4.5.2 分辨率调节
若仅需 8 倍细分,可关闭一半的缓冲器;细分倍数可灵活配置。
4.5.3 设计约束
纯缓冲器延迟单元存在单元间延时失配,必须配套电压 / 温度可调延时校准电路,否则等分精度失效。
4.6 芯片校准 FT 测试
- 片内振荡器必须 FT 校准:内部高速 HSI、低速 32K RC 振荡受 PVT 漂移极大,出厂校准才能满足时钟、HTrim、HRPWM 精度指标;
- 外部晶振无需片上校准:依靠无源器件本身精度。
4.7 国内 HRPWM / DLL 产业现状
- 技术水平分层明显:头部团队可对标海外 IP,中小厂商 DLL 模拟 IP 流片迭代成本高、指标参差不齐;
- 行业痛点:MCU 赛道同质化严重、竞争内卷,高端模拟延迟链人才流入 MCU 行业意愿低;
- 技术创新提示:延迟链 + PWM 细分属于可专利保护的模拟 / 混合信号架构,新型分频细分方案可申报发明专利。
五、基于示波器的皮秒级时间精度测量方法
作者:王建伟 日期:2018-04-02
5.1 引言
在雷达、航天、测绘、高能物理、科研及通信系统等诸多领域,多通道间时间间隔的精确测量具有重要意义。部分极端应用场景要求多通道时间间隔的测量误差低于 50 ps,甚至更小。为克服测量仪器本身的限制以实现如此高精度的时间参数测量,本文以 Agilent(现 Keysight)90000 系列示波器为例,阐述一种皮秒级时间精度测量方法。
5.2 示波器带宽与采样率要求
进行皮秒级时间测量,示波器的带宽与采样率须满足一定要求,否则信号失真将引入测量误差。
Agilent 90000 系列示波器的主要技术指标如下:
| 参数 | 指标 |
|---|---|
| 模拟带宽 | 13 GHz |
| 最高采样率 | 40 GSa/s |
| 采样点间隔 | 25 ps |
| 单通道时间测量精度(插值后) | < 5 < 5 <5 ps |
上述指标为精确测量提供了可行性基础。
5.3 通道时延校准
5.3.1 示波器自校准
示波器前面板设有快沿校准输出信号(Aux Out)。将该校准信号依次连接至各输入通道,按照校准界面提示,依次完成各通道的时延与衰减校准。具体操作方法可参考示波器《Service Guide》。
校准完成后,通道间时延误差可控制在皮秒量级( < 30 < 30 <30 ps)。该校准可由用户在现场自行完成。
5.3.2 校准周期
当满足以下任一条件时,须重新进行校准:
- 距上次校准时间超过半年;
- 校准环境温度变化超过 5 ∘ C 5\ ^\circ\text{C} 5 ∘C。
5.4 通道时延的进一步验证与修正
5.4.1 测量原理
通过电缆互换法(cross-cable method)可进一步验证并减小通道间的时延误差,其原理如下:
设示波器两个通道间的固有延时差为 Δ t ch \Delta t_{\text{ch}} Δtch,两根电缆的延时差为 Δ t cable \Delta t_{\text{cable}} Δtcable。当电缆按某一顺序连接时,测得时间差为:
T 1 = Δ t ch + Δ t cable T_1 = \Delta t_{\text{ch}} + \Delta t_{\text{cable}} T1=Δtch+Δtcable
互换两根电缆后,测得时间差为:
T 2 = Δ t ch − Δ t cable T_2 = \Delta t_{\text{ch}} - \Delta t_{\text{cable}} T2=Δtch−Δtcable
两式相加,电缆延时差被抵消,可得通道间固有延时差:
Δ t ch = T 1 + T 2 2 \Delta t_{\text{ch}} = \frac{T_1 + T_2}{2} Δtch=2T1+T2
5.4.2 操作步骤
- 将示波器的 Aux Out 输出设置为 DemoClk 输出模式;
- 经功分器将信号分为两路,通过两根等长电缆分别送至示波器的两个输入通道;
- 打开示波器的平均模式(建议 16 次或 32 次平均),测量两通道上升沿的时间差,记为 T 1 T_1 T1;
- 互换两根 BNC 电缆,再次测量两通道上升沿的时间差,记为 T 2 T_2 T2;
- 计算通道间时延差:
skew = T 1 + T 2 2 \text{skew} = \frac{T_1 + T_2}{2} skew=2T1+T2
- 在示波器通道 Skew 设置中输入上述计算值,手动调整延时;
- 再次测量 T 1 T_1 T1 与 T 2 T_2 T2,验证 T 1 ≈ − T 2 T_1 \approx -T_2 T1≈−T2。
5.4.3 精度评估
通过上述方法,示波器两通道间的时延误差以及测试电缆不等长所造成的误差基本被消除。其余不确定性因素所导致的通道时延误差可控制在 10 ps 以内。
5.5 总结
本文介绍了利用 Agilent 90000 系列示波器实现皮秒级时间精度测量的方法,主要包括:
- 选用高带宽、高采样率示波器,确保单通道时间测量精度优于 5 ps;
- 利用示波器自校准功能,将通道间时延误差控制在 30 ps 以内;
- 采用电缆互换法,进一步将通道间时延误差修正至 10 ps 以内。
该方法适用于对多通道时间间隔测量精度要求极高的应用场景。
六、结论
- ps 级 HTrim / HRPWM 思路:周期内细分,不提升主计数器工作频率,规避高频计数器时序、功耗压力;
- 方案分层选型 :
- 工业 MCU 标准 HRPWM:DLL / DPLL(模拟延迟链,4 ~ 5 bit 细分,百 ps 级);
- TI DSP 专用:MEP 微边沿;
- 超高精度时间捕获:门延迟 TDC(30 ps 级,全数字);
- 低成本平均细分:抖频;
- 设计约束:模拟类 DLL IP 受 PVT 干扰强,流片迭代成本高;纯数字 TDC 实现简单、工艺兼容性更好;
- 工艺边界:成熟 MCU 工艺(55 nm 及以上)即可实现 ps 级细分,先进 28 nm 仅提升内核主频,非细分功能刚需;
- 校准硬性要求:片内 RC 时钟出厂须 FT 校准,是 HTrim 高精度的基础前提;
- 测量验证:利用高带宽示波器(如 Agilent 90000 系列)及电缆互换法,可将多通道时延误差控制在 10 ps 以内,为 ps 级精度电路的验证与校准提供测量手段。
Reference
- 【STM32H7 教程】第 63 章 STM32H7 的高分辨率定时器 HRTIM 基础知识和 HAL 库 API-CSDN 博客
https://blog.csdn.net/Simon223/article/details/104574222- STM32H7 用户手册发布,重在 BSP 驱动包设计方法,HAL 库的框架学习- 硬汉嵌入式论坛
https://forum.anfulai.cn/forum.php?mod=viewthread&tid=86980
- STM32H7 用户手册发布,重在 BSP 驱动包设计方法,HAL 库的框架学习- 硬汉嵌入式论坛
- 【STM32】CubeMX+HAL 库之 HRTIM 多路同步独立定时器 DMA 传输比较值_stm32 hrtim-CSDN 博客
https://blog.csdn.net/weixin_45065888/article/details/120370677 -
STM32G474 单片机开发入门 (二十七)HRTIME 高精度定时器的 PWM(50KHZ) 输出实战-CSDN 博客
https://blog.csdn.net/zy2232652/article/details/153841913 - 如何用示波器进行 ps 级时间精度的测量 - 测试测量技术
https://bbs.elecfans.com/jishu_1566326_1_1.html - 经验分享 | STM32G474 高精度定时器同步功能全解析 从内部互联到多芯片协同的实现方案 - STM32团队 ST意法半导体中文论坛
https://shequ.stmicroelectronics.cn/thread-870305-1-1.html - STM32G474 高精度定时器同步功能全解析 从内部互联到多芯片协同的实现方案 - 与非网
https://www.eefocus.com/article/1978865.html - STM32G474-HRTIM 学习笔记 (1) - 缥缈日志
https://blog.liunetdisk.top/archives/231 - STM32G474-HRTIM学习笔记 (2) - 缥缈日志
https://blog.liunetdisk.top/archives/235