STM32生成高分辨率PWM-6.78MHz

0.工具与参考源

(1) STM32CubeMX 13.0 和 STM32CubeIDE 1.17.0

可以去官网下载:https://www.st.com/,没有账号就注册一个,很方便

安装路径不要有中文!

(2) Java,选的最新的JDK23.0.2 windows

Java Downloads | Oracle下载地址:Java Downloads | Oracle

(3) Deepseek

本文是用deepseek问了以下问题后整理的,感兴趣的也可以去搜一下相同问题

DeepSeek

“使用STM32G474RET6控制器,输出高分辨率pwm波的示例有吗?”

“HRTIM中四个比较值怎么配置”

“HRTIM的寄存器说明”

(4) b站视频资源 up主 cckong998的视频

STM32G474-HRTIM-四对互补移相_x264_哔哩哔哩_bilibili

(5) CSDN博客

【STM32H7教程】第63章 STM32H7的高分辨率定时器HRTIM基础知识和HAL库API-CSDN博客

因为H7也有HRTIM,所以就看了一下,讲的很详细 

(6) 官方手册

STM32G474RET6的芯片手册

https://www.st.com.cn/resource/en/datasheet/stm32g474re.pdf

STM32G474RET6的应用手册

https://www.st.com/resource/en/reference_manual/dm00355726.pdf

1.建立工程

(1) 芯片选型

我之前没用过Cube,所以直接新建工程,从MCU开始,第一次会下载一些文件

(2) 时钟配置

配置RCC-使用高速时钟,选晶振 - 右侧能看到 PF0和PF1亮了,分别是RCC_OSC_IN 和 OUT 

高速晶振为12MHz,使用锁相环 PLL来配置,PLLM /3*85/2 得到最大时钟频率170MHz

(直接在HCLK那里输入目标频率 ENTER 可以自动计算配置好各部分的分频系数)

(3) SYS模块配置

供烧写与在线调试

(4) HRTIM配置

PWM波来驱动全桥逆变器,需要两对互补输出信号,用TimerC 和 TimerD

Master Timer

设置32倍频,Master Timer 的 Period 设置为802,则周期频率为6783042Hz

Repetition Counter 设置为49

这里其实对于如何分频有一些小的注意事项

100MHz系统时钟--32倍频--472Period = 6.779661Hz;

160MHz系统时钟--32倍频--755Period = 6.781457Hz;

170MHz系统时钟--32倍频--802Period = 6.783042Hz;

本文选170MHz这个方案,一是频差可以接受,二是主频高计算也会快一点

但是如果频差为第一要素的话,第一种方案的频差是最小的

Preload 使能,Repetition update 使能,中断请求设置一个,为Repetition溢出使能

前面repetition为49,则Master Timer 每达到50次Period 则触发一次中断

中断函数中可以调节PWM波的脉宽,死区时间,移相角等等

然后配置 TimerC 和 TimerD

32倍频,但Period = 10000 因为我不需要 Timer C D来达到 他们的Period来触发事件或者中断

所以Repetition 也无所谓了,默认是0

Preload Enable,Repetition Update Disable(反正也达不到Period,默认是关)

插入死区

更新触发源 为 Master Timer 更新

置零触发源 为 Master Timer 达到Period 事件(这里的Period是Master 的Period 即 802)

使能TimerC的比较器 C_CMP1=100,C_CMP2=500

死区时间这里的分辨率略低一些,170MHz*8=1360MHz,也就是0.7353ns的分辨率

上升沿和下降沿选择14,得到约10.3ns的死区时间

PS.如果想要更高分辨率的死区的话,可以不配置插入死区,通过增加CMP3 4 来设置软件死区

配置在OUT1在计数器达到C_CMP1时置位,C_CMP2时清零

在配置完OUT1后,OUT2则自动生成,不用配置

TimerD的配置与C完全相同,不再赘述,只有D_CMP1 = 101, D_CMP2 = 501

打开中断 NVIC

(5) 比较器配置

使用COMP1比较器,PA1为输入引脚,为正输入端,负输入端选了1/2Vref

使用边沿触发中断,上升沿和下降沿都能触发中断

滞环电压为20mV

(6) NVIC配置

我需要通过COMP1触发比较器中断,在比较器中断函数中更改移相值

为了保证稳定的PWM波形,配置COMP1中断的优先级[1] 低于 HRTIM中断优先级[0]

(7) 生成代码

我还得登录一下,下载一些文件,不过也挺快的

 

(8) 注意事项

HRTIM中的CMP值是有最小值和最大值的

对于我们的32分频来说,最小值为0x0060,最大值为0xFFDF

实际配置过程中也能看到只能是96到65503,这也是为什么我们的C_CMP1要设置为100

假如C_CMP1设置为20时,即便counter达到了20,也不会触发事件,比较值无效

2.代码

生成代码后直接open project 或者 在IDE打开刚创建的代码(界面色调比Keil好看多了hhh)

(1) HRTIM部分

打开Core-Src-main.c

在USER CODE BEGIN 和 END 中间代码

记得要把自己所有的代码写在USER CODE BEGIN 和END 之间

这样CubeMX生成的代码不会覆盖写的代码段

我定义了一个全局变量 angle

// This is in the main.c
/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
uint32_t angle = 0;
/* USER CODE END PV */

记得在 main.h 中声明一下

// This is in the main.h
/* Private defines -----------------------------------------------------------*/

/* USER CODE BEGIN Private defines */
extern uint32_t angle;
/* USER CODE END Private defines */

回到 main.c 中,在main()函数中写

打开Master Timer 和 Timer C 和 Timer D

再打开C 和 D 的两组互补输出通道 

/* USER CODE BEGIN 2 */  
// HRTIM
  HAL_HRTIM_WaveformCounterStart_IT(&hhrtim1,HRTIM_TIMERID_MASTER);
  HAL_HRTIM_WaveformCounterStart(&hhrtim1,HRTIM_TIMERID_TIMER_C|HRTIM_TIMERID_TIMER_D);
  
  HAL_HRTIM_WaveformOutputStart(&hhrtim1,HRTIM_OUTPUT_TC1);
  HAL_HRTIM_WaveformOutputStart(&hhrtim1,HRTIM_OUTPUT_TC2);
  
  HAL_HRTIM_WaveformOutputStart(&hhrtim1,HRTIM_OUTPUT_TD1);
  HAL_HRTIM_WaveformOutputStart(&hhrtim1,HRTIM_OUTPUT_TD2);

/* USER CODE END 2 */

选中HAL_HRTIM_WaveformCounterStart_IT右键打开声明

可以看到这个函数在 stm32_hal_legacy.h

HAL_HRTIM_WaveformCounterStart_IT  打开计数器的同时,也打开中断

之前配置了在Master Timer的competition 寄存器溢出时会触发中断

HAL_HRTIM_WaveformCounterStart 只打开计数器 让Timer C 和 Timer D 开始计数

/** @defgroup HAL_HRTIM_Aliased_Functions HAL HRTIM Aliased Functions maintained for legacy purpose
  * @{
  */
#if defined (STM32H7) || defined (STM32G4) || defined (STM32F3)
#define HAL_HRTIM_WaveformCounterStart_IT      HAL_HRTIM_WaveformCountStart_IT
#define HAL_HRTIM_WaveformCounterStart_DMA     HAL_HRTIM_WaveformCountStart_DMA
#define HAL_HRTIM_WaveformCounterStart         HAL_HRTIM_WaveformCountStart
#define HAL_HRTIM_WaveformCounterStop_IT       HAL_HRTIM_WaveformCountStop_IT
#define HAL_HRTIM_WaveformCounterStop_DMA      HAL_HRTIM_WaveformCountStop_DMA
#define HAL_HRTIM_WaveformCounterStop          HAL_HRTIM_WaveformCountStop
#endif
/**
  * @}
  */

同样看到 函数HAL_HRTIM_WaveformOutputStart  在 stm32g4xx_hal_hrtim.c

用来使能两组互补输出

/**
  * @brief  Enable the generation of the waveform signal on the designated output(s)
  *         Outputs can be combined (ORed) to allow for simultaneous output enabling.
  * @param  hhrtim pointer to HAL HRTIM handle
  * @param  OutputsToStart Timer output(s) to enable
  *                    This parameter can be any combination of the following values:
  *                    @arg HRTIM_OUTPUT_TA1: Timer A - Output 1
  *                    @arg HRTIM_OUTPUT_TA2: Timer A - Output 2
  *                    @arg HRTIM_OUTPUT_TB1: Timer B - Output 1
  *                    @arg HRTIM_OUTPUT_TB2: Timer B - Output 2
  *                    @arg HRTIM_OUTPUT_TC1: Timer C - Output 1
  *                    @arg HRTIM_OUTPUT_TC2: Timer C - Output 2
  *                    @arg HRTIM_OUTPUT_TD1: Timer D - Output 1
  *                    @arg HRTIM_OUTPUT_TD2: Timer D - Output 2
  *                    @arg HRTIM_OUTPUT_TE1: Timer E - Output 1
  *                    @arg HRTIM_OUTPUT_TE2: Timer E - Output 2
  *                    @arg HRTIM_OUTPUT_TF1: Timer F - Output 1
  *                    @arg HRTIM_OUTPUT_TF2: Timer F - Output 2
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HRTIM_WaveformOutputStart(HRTIM_HandleTypeDef *hhrtim,
                                                uint32_t OutputsToStart)
{
  /* Check the parameters */
  assert_param(IS_HRTIM_OUTPUT(OutputsToStart));

  /* Process Locked */
  __HAL_LOCK(hhrtim);

  hhrtim->State = HAL_HRTIM_STATE_BUSY;

  /* Enable the HRTIM outputs */
  hhrtim->Instance->sCommonRegs.OENR |= (OutputsToStart);

  hhrtim->State = HAL_HRTIM_STATE_READY;

  /* Process Unlocked */
  __HAL_UNLOCK(hhrtim);

  return HAL_OK;
}

打开Core-Src- hrtim.c  写 HRTIM的回调函数 HAL_HRTIM_RepetitionEventCallback

因为程序中只有Master Timer 的Repetition 溢出会触发中断,所以不用判断是不是MASTER了

然后根据angle的值更改CMP1 和 CMP2

这里是直接操作寄存器的值

只改变TD的 D_CMP1 和 D_CMP2 的值

/* USER CODE BEGIN 1 */
void HAL_HRTIM_RepetitionEventCallback(HRTIM_HandleTypeDef * hhrtim , uint32_t TimerIdx)
{
	/* only Master IT is enabled, so no need to judge;
	 * if (TimerIdx == HRTIM_TIMERID_MASTER)
	    {
	    }
	 */
	// my function to change the CMP
	/* sTimerxRegs[0] - TimerA
	 * sTimerxRegs[1] - TimerB
	 * sTimerxRegs[2] - TimerC
	 * sTimerxRegs[3] - TimerD
	 * sTimerxRegs[4] - TimerE
	 * sTimerxRegs[5] - TimerF
	 * */
	if(angle == 90){
		HRTIM1->sTimerxRegs[3].CMP1xR = 200;
		HRTIM1->sTimerxRegs[3].CMP2xR = 600;
	}
	else {
		HRTIM1->sTimerxRegs[3].CMP1xR = 101;
		HRTIM1->sTimerxRegs[3].CMP2xR = 501;
	}

}
/* USER CODE END 1 */

sTimerxRegs 在 stm32g474xx.h 中 

能看到sTimerxRegs结构体中寄存器的值,而TimerC 和 TimerD 是[2] 和 [3]

/* HRTIM Timer A to F registers definition */
typedef struct
{
  __IO uint32_t TIMxCR;     /*!< HRTIM Timerx control register,                              Address offset: 0x00  */
  __IO uint32_t TIMxISR;    /*!< HRTIM Timerx interrupt status register,                     Address offset: 0x04  */
  __IO uint32_t TIMxICR;    /*!< HRTIM Timerx interrupt clear register,                      Address offset: 0x08  */
  __IO uint32_t TIMxDIER;   /*!< HRTIM Timerx DMA/interrupt enable register,                 Address offset: 0x0C  */
  __IO uint32_t CNTxR;      /*!< HRTIM Timerx counter register,                              Address offset: 0x10  */
  __IO uint32_t PERxR;      /*!< HRTIM Timerx period register,                               Address offset: 0x14  */
  __IO uint32_t REPxR;      /*!< HRTIM Timerx repetition register,                           Address offset: 0x18  */
  __IO uint32_t CMP1xR;     /*!< HRTIM Timerx compare 1 register,                            Address offset: 0x1C  */
  __IO uint32_t CMP1CxR;    /*!< HRTIM Timerx compare 1 compound register,                   Address offset: 0x20  */
  __IO uint32_t CMP2xR;     /*!< HRTIM Timerx compare 2 register,                            Address offset: 0x24  */
  __IO uint32_t CMP3xR;     /*!< HRTIM Timerx compare 3 register,                            Address offset: 0x28  */
  __IO uint32_t CMP4xR;     /*!< HRTIM Timerx compare 4 register,                            Address offset: 0x2C  */
  __IO uint32_t CPT1xR;     /*!< HRTIM Timerx capture 1 register,                            Address offset: 0x30  */
  __IO uint32_t CPT2xR;     /*!< HRTIM Timerx capture 2 register,                            Address offset: 0x34 */
  __IO uint32_t DTxR;       /*!< HRTIM Timerx dead time register,                            Address offset: 0x38 */
  __IO uint32_t SETx1R;     /*!< HRTIM Timerx output 1 set register,                         Address offset: 0x3C */
  __IO uint32_t RSTx1R;     /*!< HRTIM Timerx output 1 reset register,                       Address offset: 0x40 */
  __IO uint32_t SETx2R;     /*!< HRTIM Timerx output 2 set register,                         Address offset: 0x44 */
  __IO uint32_t RSTx2R;     /*!< HRTIM Timerx output 2 reset register,                       Address offset: 0x48 */
  __IO uint32_t EEFxR1;     /*!< HRTIM Timerx external event filtering 1 register,           Address offset: 0x4C */
  __IO uint32_t EEFxR2;     /*!< HRTIM Timerx external event filtering 2 register,           Address offset: 0x50 */
  __IO uint32_t RSTxR;      /*!< HRTIM Timerx Reset register,                                Address offset: 0x54 */
  __IO uint32_t CHPxR;      /*!< HRTIM Timerx Chopper register,                              Address offset: 0x58 */
  __IO uint32_t CPT1xCR;    /*!< HRTIM Timerx Capture 1 register,                            Address offset: 0x5C */
  __IO uint32_t CPT2xCR;    /*!< HRTIM Timerx Capture 2 register,                            Address offset: 0x60 */
  __IO uint32_t OUTxR;      /*!< HRTIM Timerx Output register,                               Address offset: 0x64 */
  __IO uint32_t FLTxR;      /*!< HRTIM Timerx Fault register,                                Address offset: 0x68 */
  __IO uint32_t TIMxCR2;    /*!< HRTIM Timerx Control register 2,                            Address offset: 0x6C */
  __IO uint32_t EEFxR3;     /*!< HRTIM Timerx external event filtering 3 register,           Address offset: 0x70 */
  uint32_t   RESERVED0[3];  /*!< Reserved,                                                   0x74..0x7C */
}HRTIM_Timerx_TypeDef;

/* HRTIM  register definition */
typedef struct {
  HRTIM_Master_TypeDef sMasterRegs;
  HRTIM_Timerx_TypeDef sTimerxRegs[6];
  HRTIM_Common_TypeDef sCommonRegs;
}HRTIM_TypeDef;

(2) COMP1部分

还是在main.c而且记得写在USER CODE中

打开COMP

// COMP
  HAL_COMP_Start(&hcomp1);

  /* USER CODE END 2 */

stm32g4xx_hal_comp.c到 HAL_COMP_Start()

我是没什么好看的,列在这里

/**
  * @brief  Start the comparator.
  * @param  hcomp  COMP handle
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_COMP_Start(COMP_HandleTypeDef *hcomp)
{
  __IO uint32_t wait_loop_index = 0UL;
  HAL_StatusTypeDef status = HAL_OK;

  /* Check the COMP handle allocation and lock status */
  if (hcomp == NULL)
  {
    status = HAL_ERROR;
  }
  else if (__HAL_COMP_IS_LOCKED(hcomp))
  {
    status = HAL_ERROR;
  }
  else
  {
    /* Check the parameter */
    assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));

    if (hcomp->State == HAL_COMP_STATE_READY)
    {
      /* Enable the selected comparator */
      SET_BIT(hcomp->Instance->CSR, COMP_CSR_EN);

      /* Set HAL COMP handle state */
      hcomp->State = HAL_COMP_STATE_BUSY;

      /* Delay for COMP startup time */
      /* Wait loop initialization and execution */
      /* Note: Variable divided by 2 to compensate partially                  */
      /*       CPU processing cycles.                                         */
      /* Note: In case of system low frequency (below 1Mhz), short delay      */
      /*       of startup time (few us) is within CPU processing cycles       */
      /*       of following instructions.                                     */
      wait_loop_index = (COMP_DELAY_STARTUP_US * (SystemCoreClock / (1000000UL * 2UL)));
      while (wait_loop_index != 0UL)
      {
        wait_loop_index--;
      }
    }
    else
    {
      status = HAL_ERROR;
    }
  }

  return status;
}

之前配置了比较器在超过 1/2Vref 时,上升沿触发中断

在 comp.c 中 写 回调函数 HAL_COMP_TriggerCallback

angle是之前自定义的一个全局变量

先判断进入这个中断是COMP1 //这一步其实可以省略,我没删掉而已

然后用 HAL_COMP_GetOutputLevel() 这个函数提取输出电平

COMP_OUTPUT_LEVEL_HIGH 为高电平

如果比较器输出为高电平,angle为90;如果低电平, angle为1;

/* USER CODE BEGIN 1 */
void HAL_COMP_TriggerCallback(COMP_HandleTypeDef *hcomp)
{
	
	if(hcomp->Instance == COMP1){
		if(HAL_COMP_GetOutputLevel(&hcomp1) == COMP_OUTPUT_LEVEL_HIGH) angle = 90;
		else angle = 1;
	}

}

/* USER CODE END 1 */

 HAL_COMP_GetOutputLevel() 在 stm32g4xx_hal_comp.c

读取选择的寄存器的输出电平

这里也能看到输出值 COMP_OUTPUT_LEVEL_HIGH 和 COMP_OUTPUT_LEVEL_LOW

/**
  * @brief  Return the output level (high or low) of the selected comparator.
  *         On this STM32 series, comparator 'value' is taken before
  *         polarity and blanking are applied, thus:
  *           - Comparator output is low when the input plus is at a lower
  *             voltage than the input minus
  *           - Comparator output is high when the input plus is at a higher
  *             voltage than the input minus
  * @param  hcomp  COMP handle
  * @retval Returns the selected comparator output level:
  *         @arg COMP_OUTPUT_LEVEL_LOW
  *         @arg COMP_OUTPUT_LEVEL_HIGH
  *
  */
uint32_t HAL_COMP_GetOutputLevel(const COMP_HandleTypeDef *hcomp)
{
  /* Check the parameter */
  assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));

  return (uint32_t)(READ_BIT(hcomp->Instance->CSR, COMP_CSR_VALUE)
                    >> COMP_OUTPUT_LEVEL_BITOFFSET_POS);
}

3. 检验

(1) TC1 和 TC2 的波形

输出PWM的频率 6.782MHz 

死区时间 10.24ns

导通时间 63.38ns

(2) TC1 和 TD1 的波形

比较器输出高电平 -- angle为90

C_CMP1 为100;C_CMP2 为500

D_CMP1 为200;D_CMP2 为600

(3) TC1 和 TD1 的波形

比较器输出低电平 -- angle为1

C_CMP1 为100;C_CMP2 为500

D_CMP1 为101;D_CMP2 为501

4. 感谢参考的博主和学弟

希望大家都来做6.78MHz!

### STM32G474RET6 配置和输出 PWM 信号 STM32G474RET6 微控制器支持通过高级定时器(TIMx)或 HRTIM 模块生成高分辨率 PWM 信号。HRTIM 是一种高性能定时器模块,能够实现高达 6.78 MHzPWM 输出频率[^1]。 以下是基于 HAL 库的配置方法以及示例代码: #### 使用 TIMx 定时器生成标准 PWM 对于较低频率的需求,可以使用通用定时器(如 TIM1 或 TIM2)。以下是一个简单的配置流程: 1. **启用外设时钟** 在初始化阶段,需开启对应定时器的时钟。 ```c __HAL_RCC_TIM1_CLK_ENABLE(); ``` 2. **配置 GPIO 引脚** 将用于输出 PWM 的引脚设置为复用功能模式,并连接到对应的定时器通道。 ```c GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOA_CLK_ENABLE(); // 假设使用 PA8 (TIM1_CH1) GPIO_InitStruct.Pin = GPIO_PIN_8; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; // 复用推挽输出 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Alternate = GPIO_AF1_TIM1; // 设置为 TIM1 的 AF HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); ``` 3. **配置定时器参数** 初始化定时器并设定预分频器值及时基周期。 ```c TIM_HandleTypeDef htim1; htim1.Instance = TIM1; htim1.Init.Prescaler = 83; // APB2 时钟假设为 84MHz,则计数频率为 1MHz htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = 999; // 计数值范围为 0~999,即 1kHz PWM 频率 htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; if (HAL_TIM_PWM_Init(&htim1) != HAL_OK) { Error_Handler(); } ``` 4. **配置 PWM 通道** 设定占空比并通过 HAL 函数启动 PWM 输出。 ```c TIM_OC_InitTypeDef sConfigOC; sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 500; // 占空比为 50% sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); // 启动 PWM 输出 ``` --- #### 使用 HRTIM 模块生成高分辨率 PWM 如果需要更高精度或更高速度的 PWM 波形,可利用 HRTIM 模块。其核心步骤如下: 1. **使能 HRTIM 和相关 GPIO 时钟** ```c __HAL_RCC_HRTIM1_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); // 假设使用 PE9 (HRTIM1 Timer A Output) ``` 2. **配置 GPIO 引脚** ```c GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Alternate = GPIO_AF11_HRTIM1; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); ``` 3. **初始化 HRTIM 结构体** ```c HRTIM_TimeBaseInitTypeDef pTimeBaseCfg; HRTIM_OutputInitTypeDef pOutputCfg; HRTIM_TimerInitTypeDef pTimerACfg; /* 时间基准配置 */ pTimeBaseCfg.SyncSource = HRTIM_SYNCSOURCE_INTERNAL; pTimeBaseCfg.HalfCycleEnable = ENABLE; pTimeBaseCfg.RepetitionCounter = 0; pTimeBaseCfg.PrescalerRatio = HRTIM_PRESCALERRATIO_MUL1; pTimeBaseCfg.TickPrescaler = HRTIM_TICKPRESCALER_DIV1; /* 定时器 A 配置 */ pTimerACfg.TimerMode = HRTIM_TIMERMODE_CONTINUOUS; pTimerACfg.UpdateSource = HRTIM_UPDATE_SOURCE_REGULAR; pTimerACfg.OutputRedirection = HRTIM_OUTPUTREDIRECTION_NONE; pTimerACfg.DeadTimeInsertion = DISABLE; pTimerACfg.ResetOnSync = ENABLE; /* 输出配置 */ pOutputCfg.Polarity = HRTIM_OUTPUTPOLARITY_NONINVERTED; pOutputCfg.SetSource = HRTIM_SETSOURCE_MASTERCMP1; pOutputCfg.ResetSource = HRTIM_RESETSOURCE_MASTERPERIOD; pOutputCfg.IdleState = HRTIM_OUTPUTIDLESTATE_LOW; pOutputCfg.FaultState = HRTIM_OUTPUTFAULTSTATE_LOW; pOutputCfg.ChopperModeEnable = DISABLE; pOutputCfg.BurstModeEntryDelayed = DISABLE; /* 初始化 HRTIM */ if (HAL_HRTIM_TimeBaseInit(&hhrtim1, HRTIM_TIMERINDEX_MASTER, &pTimeBaseCfg) != HAL_OK || HAL_HRTIM_MasterCompareWrite(&hhrtim1, HRTIM_TIMERINDEX_MASTER, HRTIM_COMPAREUNIT_1, 6000) != HAL_OK || // 主比较寄存器写入值 HAL_HRTIM_SetOneShotMode(&hhrtim1, HRTIM_TIMERINDEX_MASTER, DISABLE) != HAL_OK || HAL_HRTIM_WaveformOutputStart(&hhrtim1, HRTIM_OUTPUT_TA1) != HAL_OK) { // 开始波形输出 Error_Handler(); } ``` 上述代码片段展示了如何通过 HRTIM 实现高频 PWM 输出的功能。 --- ### 注意事项 - 确保正确计算预分频器与时基周期以满足目标频率需求。 - 对于 HRTIM 模块的操作,建议仔细阅读《STM32G4 Series Reference Manual》中的相关内容。 - 如果需要调试,可以通过逻辑分析仪观察实际波形是否符合预期。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值