[STM32G4] 使用 STM32G431 实现 PWM 控制风扇速度的详细教程

[复制链接]
3103|11
 楼主| 帛灿灿 发表于 2024-12-7 07:39 | 显示全部楼层 |阅读模式
在电子产品设计中,精确地控制直流风扇的转速是一个常见需求,特别是在散热管理和功耗优化中。本文将以 STM32G431 微控制器为例,讲解如何通过 PWM(脉宽调制)信号来实现风扇转速的精确控制。STM32G431 是一款基于 ARM Cortex-M4 内核的高性能 MCU,具有丰富的外设资源,适合用于实时控制和电机驱动等应用。

1. 硬件连接在实际连接中,风扇的 PWM 控制引脚需要与 STM32 的一个定时器输出通道相连,同时为风扇提供合适的电源。下面是一个典型的连接方法:
  • STM32G431 的 TIM1_CH1 引脚连接到风扇的 PWM 输入引脚。
  • 风扇电源通过稳压电路供电(例如 12V)。
  • 地线需与 MCU 共地。

2. 配置思路实现风扇转速控制的关键是生成合适的 PWM 信号,控制步骤如下:
  • 配置 STM32 的时钟,确保定时器运行在合适频率。
  • 初始化 TIM1 定时器,将其设置为 PWM 模式。
  • 设置 PWM 的占空比,根据占空比调整风扇转速。
  • 编写代码实现风扇速度的动态调整。

3. 代码实现以下代码展示了如何使用 STM32CubeMX 生成初始化代码,并基于 HAL 库实现风扇的 PWM 控制。
  1. #include "main.h"

  2. // 定义 PWM 占空比变量
  3. uint16_t pwmDutyCycle = 50; // 初始占空比为 50%

  4. void SystemClock_Config(void);
  5. static void MX_GPIO_Init(void);
  6. static void MX_TIM1_Init(void);

  7. // TIM1 句柄定义
  8. TIM_HandleTypeDef htim1;

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

  14.     // 启动 TIM1 PWM 输出
  15.     HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);

  16.     while (1) {
  17.         // 模拟调整 PWM 占空比
  18.         for (pwmDutyCycle = 0; pwmDutyCycle <= 100; pwmDutyCycle += 10) {
  19.             __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, pwmDutyCycle);
  20.             HAL_Delay(500); // 每次调整后延迟 500ms
  21.         }
  22.     }
  23. }

  24. static void MX_TIM1_Init(void) {
  25.     TIM_OC_InitTypeDef sConfigOC = {0};
  26.    
  27.     htim1.Instance = TIM1;
  28.     htim1.Init.Prescaler = 80 - 1; // 80 MHz 主频分频到 1 MHz
  29.     htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  30.     htim1.Init.Period = 100 - 1; // PWM 频率为 10 kHz
  31.     htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  32.     htim1.Init.RepetitionCounter = 0;
  33.     HAL_TIM_PWM_Init(&htim1);

  34.     sConfigOC.OCMode = TIM_OCMODE_PWM1;
  35.     sConfigOC.Pulse = 50; // 初始占空比为 50%
  36.     sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  37.     sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  38.     HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);
  39. }

  40. static void MX_GPIO_Init(void) {
  41.     __HAL_RCC_GPIOA_CLK_ENABLE(); // 启用 GPIOA 时钟
  42.     GPIO_InitTypeDef GPIO_InitStruct = {0};
  43.     GPIO_InitStruct.Pin = GPIO_PIN_8; // TIM1_CH1 对应的引脚
  44.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  45.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  46.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  47.     GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
  48.     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  49. }

  50. void SystemClock_Config(void) {
  51.     // 配置时钟,具体配置根据需求调整
  52.     RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  53.     RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  54.     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  55.     RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  56.     RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  57.     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  58.     RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  59.     RCC_OscInitStruct.PLL.PLLM = 1;
  60.     RCC_OscInitStruct.PLL.PLLN = 8;
  61.     RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
  62.     RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  63.     RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  64.     HAL_RCC_OscConfig(&RCC_OscInitStruct);

  65.     RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK |
  66.                                   RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
  67.     RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  68.     RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  69.     RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  70.     RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  71.     HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4);
  72. }
4. 总结通过上述代码,STM32G431 可以生成一个 PWM 信号,用于控制风扇的转速。代码中定时器的设置灵活,可根据实际需求调整频率和占空比范围。将 PWM 信号接入风扇的控制引脚,即可实现动态转速调整。

公羊子丹 发表于 2024-12-7 07:39 | 显示全部楼层
这个教程太详细了,正好我手上有个 STM32G431,可以试试。
周半梅 发表于 2024-12-7 07:39 | 显示全部楼层
学习了,原来 TIM1 还能这么玩!
 楼主| 帛灿灿 发表于 2024-12-7 07:40 | 显示全部楼层
用 STM32 控风扇转速,真是硬核操作。
万图 发表于 2024-12-7 07:40 | 显示全部楼层
感觉这个代码很好理解,新手也能快速上手。
Wordsworth 发表于 2024-12-7 07:40 | 显示全部楼层
有没有建议的风扇型号?我怕买错了用不了。
Bblythe 发表于 2024-12-7 07:40 | 显示全部楼层
TIM 的分频和占空比这块,我还需要多看几遍才能搞明白。
Pulitzer 发表于 2024-12-7 07:40 | 显示全部楼层
10kHz 的 PWM 频率对一般风扇够用吗?
Uriah 发表于 2024-12-7 07:41 | 显示全部楼层
要是加上外部温度传感器,就可以自动调速了,感觉挺实用。
Clyde011 发表于 2024-12-7 07:41 | 显示全部楼层
想问下,这种控制方法适用于无刷风扇吗?
结合国际经验 发表于 2024-12-31 23:10 | 显示全部楼层
在 STM32CubeMX 生成的代码基础上,我们可以使用 HAL 库进行 CAN 总线通信的实现。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

172

主题

6262

帖子

0

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