[STM32G4] STM32G431的定时器高级功能:PWM输出控制

[复制链接]
2226|9
 楼主| Uriah 发表于 2024-12-5 15:04 | 显示全部楼层 |阅读模式
随着嵌入式应用对精度和功能要求的提高,ST Microelectronics的STM32系列MCU以其强大的功能和灵活性,成为工程师们开发项目的热门选择。本文将以STM32G431为例,重点介绍如何利用其定时器的PWM功能控制外设,展示代码实现和应用场景。
为什么选择STM32G431?STM32G431属于STM32G4系列,采用Cortex-M4内核,主频高达170MHz。它不仅拥有丰富的模拟外设(如高分辨率定时器和12位ADC),还支持CAN、I2C和UART等多种通信接口。尤其是在对高精度和高性能要求的电机控制和电源转换领域,STM32G431表现尤为出色。
PWM功能概述脉宽调制(PWM)是一种通过调整信号占空比来控制能量输出的技术,广泛应用于LED调光、电机转速控制等场景。STM32G431的定时器支持多种PWM模式,包括边沿对齐模式和中心对齐模式,工程师可以根据具体需求灵活选择。
实现步骤以下通过配置TIM1定时器来生成PWM信号,具体步骤如下:
  • 配置时钟树,启用定时器外设的时钟。
  • 初始化GPIO,设置对应引脚为定时器的PWM输出。
  • 配置TIM1的频率、占空比和模式。
  • 启动PWM输出。
代码实现以下是基于STM32G431的HAL库实现PWM信号输出的完整代码:
  1. #include "stm32g4xx_hal.h"

  2. // 定义占空比
  3. #define PWM_DUTY_CYCLE 50 // 50%

  4. // 定义PWM频率
  5. #define PWM_FREQUENCY 10000 // 10 kHz

  6. TIM_HandleTypeDef htim1;

  7. void SystemClock_Config(void);
  8. static void MX_GPIO_Init(void);
  9. static void MX_TIM1_Init(void);

  10. int main(void) {
  11.     HAL_Init();
  12.     SystemClock_Config();
  13.     MX_GPIO_Init();
  14.     MX_TIM1_Init();

  15.     // 启动TIM1的PWM通道1
  16.     HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);

  17.     while (1) {
  18.         // 主循环留空,可扩展为动态调整占空比的逻辑
  19.     }
  20. }

  21. void SystemClock_Config(void) {
  22.     RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  23.     RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  24.     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  25.     RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  26.     RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  27.     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  28.     RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  29.     RCC_OscInitStruct.PLL.PLLM = 1;
  30.     RCC_OscInitStruct.PLL.PLLN = 8;
  31.     RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  32.     RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  33.     RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;

  34.     HAL_RCC_OscConfig(&RCC_OscInitStruct);

  35.     RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
  36.                                   | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
  37.     RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  38.     RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  39.     RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  40.     RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  41.     HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
  42. }

  43. static void MX_GPIO_Init(void) {
  44.     __HAL_RCC_GPIOA_CLK_ENABLE();
  45.     GPIO_InitTypeDef GPIO_InitStruct = {0};

  46.     GPIO_InitStruct.Pin = GPIO_PIN_8; // PA8为TIM1_CH1
  47.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  48.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  49.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  50.     GPIO_InitStruct.Alternate = GPIO_AF6_TIM1;
  51.     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  52. }

  53. static void MX_TIM1_Init(void) {
  54.     TIM_OC_InitTypeDef sConfigOC = {0};

  55.     htim1.Instance = TIM1;
  56.     htim1.Init.Prescaler = HAL_RCC_GetPCLK2Freq() / (PWM_FREQUENCY * 10000) - 1;
  57.     htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  58.     htim1.Init.Period = 10000 - 1; // 10kHz对应的计数值
  59.     htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  60.     htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;

  61.     HAL_TIM_PWM_Init(&htim1);

  62.     sConfigOC.OCMode = TIM_OCMODE_PWM1;
  63.     sConfigOC.Pulse = (htim1.Init.Period + 1) * PWM_DUTY_CYCLE / 100;
  64.     sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  65.     sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

  66.     HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);
  67. }
总结通过上述代码,我们成功实现了STM32G431定时器的PWM输出功能。该代码仅展示了基本配置,实际项目中还可结合DMA、外部中断或其他外设进一步优化。STM32G431强大的功能使得它成为高性能嵌入式应用的理想选择。

公羊子丹 发表于 2024-12-5 15:05 | 显示全部楼层
哇,这个代码写得好详细啊,我要马上试试!
周半梅 发表于 2024-12-5 15:05 | 显示全部楼层
没想到PWM还能这么灵活地控制,学习了!
帛灿灿 发表于 2024-12-5 15:05 | 显示全部楼层
STM32G431确实是性价比超高的一款芯片啊!
童雨竹 发表于 2024-12-5 15:06 | 显示全部楼层
代码注释很清晰,新手也能看懂,棒!
万图 发表于 2024-12-5 15:06 | 显示全部楼层
文章说的应用场景很实用,特别是电机控制部分。
Wordsworth 发表于 2024-12-5 15:06 | 显示全部楼层
有没有办法动态调节占空比呢?想尝试更复杂的功能。
Pulitzer 发表于 2024-12-5 15:06 | 显示全部楼层
TIM1居然能这么精细地配置,ST的工程师是真厉害!
Bblythe 发表于 2024-12-5 15:06 | 显示全部楼层
用HAL库写代码,开发效率果然高了不少!
Clyde011 发表于 2024-12-5 15:07 | 显示全部楼层
期待下一篇关于DMA触发PWM的教程!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

161

主题

6251

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部