STM32G474单片机开发入门(二十七)HRTIME高精度定时器的PWM(50KHZ)输出实战
文章目录
- 一.概要
- 二.HRTIM高精度定时器特色
- 三.HRTIM高精度定时器框图
- 四.CubeMX配置HRTIM1输出50KHZ PWM波例程
- 1.硬件准备
- 2.创建CubeMX工程
- 3.测量波形结果
- 五.小结
一.概要
我们在STM32G474单片机开发入门(七)定时器PWM波输出与输入实战中介绍了脉冲宽度调制(PWM),是用TIM2_CH4实现输出,TIM2是一个通用定时器,STM32G474的特色就是还有一个高精度定时器HRTIM,接下去我们介绍下这个高精度定时器,以及如何用这个HRTIM定时器输出PWM波。

二.HRTIM高精度定时器特色
1.超高时间分辨率
通过170MHz,32倍频到5.44GHz,实现184ps分辨率,支持精确的PWM占空比和频率调整。我们原先的TIM1,TIM2定时时期时钟倍频只能到10ns级别的分辨率,所以HRTIM的精度高很多。HRTIM高精度定时器的定时单元还针对电压/温度变化进行补偿,确保稳定性。
2.多通道灵活控制
包含6个独立16位定时单元,每个单元带4个比较单元,可控制12个输出通道,每个通道支持最多32个设置/重置源。模块化架构适合多开关电源拓扑。
3.高级PWM功能
支持死区插入和互补PWM输出(通过软件配置实现硬件级互补)。提供Burst模式,可编程运行/空闲状态交替周期,降低开关损耗,支持单脉冲模式、重复计数和故障保护机制。
典型应用场景包括高频开关电源(如Buck-Bo拓扑)、电机控制和逆变系统。需注意其PWM配置复杂度较高,需合理设置Master Timer事件触发以避免丢波现象。
三.HRTIM高精度定时器框图

HRTIM内部结构框图如上所示,HRTIM包含1个主Master timer定时器单元,6个子定时器单元(A,B,C,D,E,F),这7个定时器单元,每个定时器单元可独立使用,亦可与其他耦合使用。
6个子定时器单元,每个单元内含:
• 16-bit 计数器
• 4x 16-bit 比较寄存器
• 2x 16-bit 捕获寄存器
• 2路PWM输出
Master timer定时器基于5.44GHz时钟驱动,提供184ps的超高分辨率,Master timer定时器没有PWM输出功能,子定时器可通过总线接收Master Timer的同步事件(如计数器复位、启动/停止计数)。
四.CubeMX配置HRTIM1输出50KHZ PWM波例程
1.硬件准备
STLINK接STM32G474RET6开发板,STLINK接电脑USB口,示波器探头接PB14脚。

2.创建CubeMX工程
如下图所示,打开STM32CubeMX软件,新建工程。

如下图所示,Part Number处输入STM32G474RE,再双击就创建新的工程。

如下图所示,配置下载口引脚,PA13为SWD的SWDIO脚,PA14为SWD的SWCLK脚。

如下图所示,配置HRTIM1,50Khz,50%占空比的PWM输出,PB14为PWM输出引脚。


如下图所示,配置系统主频170Mhz,使用外部8MHZ晶振。

配置工程文件名,保存路径,KEIL5工程输出方式,生成工程。


如下图所示,增加代码,添加PWM输出使能。

如下图所示,增加代码,添加TIMD_PERIOD分频系数宏定义,根据时钟频率,周期决定,倍频系数这里选择16,如果频率比较低,需要调低倍频系数。

主要代码如下
#define HRTIM_INPUT_CLOCK 170000000
#define TIMD_PWM_FREQ 50000
#define TIMD_DUTY_CYCLE 0.5
//由于有最低频率的限制,所以不同的频率可能需要修改宏定义
//比如100KHZ的PWM,宏定义需要改成#define TIMD_PERIOD ((uint16_t)((((uint64_t)HRTIM_INPUT_CLOCK) * 32) / TIMD_PWM_FREQ))
//同时初始化中同步修改pTimeBaseCfg.PrescalerRatio = HRTIM_PRESCALERRATIO_MUL32;
#define TIMD_PERIOD ((uint16_t)((((uint64_t)HRTIM_INPUT_CLOCK) * 16) / TIMD_PWM_FREQ))//定义周期//#define HRTIM_PRESCALERRATIO_MUL32 (0x00000000U) /*!< fHRCK: fHRTIM x 32U = 4.608 GHz - Resolution: 217 ps - Min PWM frequency: 70.3 kHz (fHRTIM=144MHz) */
//#define HRTIM_PRESCALERRATIO_MUL16 (0x00000001U) /*!< fHRCK: fHRTIM x 16U = 2.304 GHz - Resolution: 434 ps - Min PWM frequency: 35.1 KHz (fHRTIM=144MHz) */
//#define HRTIM_PRESCALERRATIO_MUL8 (0x00000002U) /*!< fHRCK: fHRTIM x 8U = 1.152 GHz - Resolution: 868 ps - Min PWM frequency: 17.6 kHz (fHRTIM=144MHz) */
//#define HRTIM_PRESCALERRATIO_MUL4 (0x00000003U) /*!< fHRCK: fHRTIM x 4U = 576 MHz - Resolution: 1.73 ns - Min PWM frequency: 8.8 kHz (fHRTIM=144MHz) */
//#define HRTIM_PRESCALERRATIO_MUL2 (0x00000004U) /*!< fHRCK: fHRTIM x 2U = 288 MHz - Resolution: 3.47 ns - Min PWM frequency: 4.4 kHz (fHRTIM=144MHz) */
//#define HRTIM_PRESCALERRATIO_DIV1 (0x00000005U) /*!< fHRCK: fHRTIM = 144 MHz - Resolution: 6.95 ns - Min PWM frequency: 2.2 kHz (fHRTIM=144MHz) */
//#define HRTIM_PRESCALERRATIO_DIV2 (0x00000006U) /*!< fHRCK: fHRTIM / 2U = 72 MHz - Resolution: 13.88 ns- Min PWM frequency: 1.1 kHz (fHRTIM=144MHz) */
//#define HRTIM_PRESCALERRATIO_DIV4 (0x00000007U) /*!< fHRCK: fHRTIM / 4U = 36 MHz - Resolution: 27.7 ns- Min PWM frequency: 550Hz (fHRTIM=144MHz) /* USER CODE END 0 */HRTIM_HandleTypeDef hhrtim1;/* HRTIM1 init function */
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();}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 = 0x00;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 = 0x0000;pTimerCfg.DMADstAddress = 0x0000;pTimerCfg.DMASize = 0x1;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 = 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 Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();//8M外部晶振,170M系统主频/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_HRTIM1_Init();//HRTIME初始化,PWM频率为50K,占空比50%,PB14:HRTIM1_CHD1/* USER CODE BEGIN 2 */HAL_HRTIM_WaveformOutputStart(&hhrtim1, HRTIM_OUTPUT_TD1);//启动波形输出的函数调用,TD1输出波形HAL_HRTIM_WaveformCounterStart(&hhrtim1, HRTIM_TIMERID_TIMER_D);//启动定时器D的波形计数功能/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}
3.测量波形结果
通过示波器测量PB14引脚,可以看到PWM输出是50Khz,占空比50%。

五.小结
STM32G474RET6通过HRTIM实现1/256微步控制,适用于CNC机床和3D打印机,支持PMSM电机磁场定向控制,用于无人机和电动工具驱动,通过多个定时器同步控制机械臂协同运动,在数字电源开发中表现突出,其HRTIM模块的184ps分辨率可实现纳秒级时序控制。
