[STM32G4] STM32G431开发指南:快速实现PWM输出功能

[复制链接]
2957|9
 楼主| Pulitzer 发表于 2024-11-29 07:49 | 显示全部楼层 |阅读模式
随着嵌入式开发的不断深入,STM32系列微控制器凭借其强大的性能和丰富的外设资源,成为了工程师们的首选。在这篇文章中,我们将以STM32G431为例,讲解如何实现PWM(脉宽调制)输出功能,从代码实现到实际应用,让你快速掌握这一常用功能。

什么是PWM?PWM(Pulse Width Modulation)是一种通过改变脉冲宽度来调节输出信号的技术,广泛应用于电机控制、LED调光、音频信号生成等领域。通过STM32G431的高级定时器,我们可以轻松生成精确的PWM信号。

工程准备在开始之前,你需要准备以下材料:
  • STM32G431开发板(例如Nucleo-G431RB)
  • ST-LINK调试器
  • Keil、STM32CubeIDE或其他开发工具
  • STM32CubeMX初始化代码生成工具
我们将以TIM1定时器的通道1为例,生成50Hz的PWM信号,并且占空比可以调节。

PWM实现步骤
  • 配置硬件资源使用STM32CubeMX配置TIM1为PWM模式,并将输出引脚设置为PA8(TIM1_CH1)。
  • 初始化代码生成利用STM32CubeMX生成初始化代码,并在生成的工程中补充PWM控制代码。
  • 编写主程序在主程序中初始化PWM并设置占空比。


代码实现以下是实现50Hz PWM信号的完整代码,支持动态调整占空比:
  1. #include "main.h"

  2. // 定义PWM占空比
  3. uint32_t dutyCycle = 50; // 默认50%

  4. // PWM初始化函数
  5. void PWM_Init(void) {
  6.     HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); // 启动PWM
  7. }

  8. // 调节占空比函数
  9. void Set_PWM_DutyCycle(uint32_t duty) {
  10.     if (duty <= 100) {
  11.         __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, (htim1.Init.Period + 1) * duty / 100);
  12.     }
  13. }

  14. int main(void) {
  15.     HAL_Init(); // 初始化HAL库
  16.     SystemClock_Config(); // 配置系统时钟
  17.     MX_GPIO_Init(); // 初始化GPIO
  18.     MX_TIM1_Init(); // 初始化TIM1

  19.     PWM_Init(); // 启动PWM

  20.     while (1) {
  21.         // 动态调节占空比
  22.         for (dutyCycle = 0; dutyCycle <= 100; dutyCycle += 10) {
  23.             Set_PWM_DutyCycle(dutyCycle);
  24.             HAL_Delay(500); // 每500ms调整一次
  25.         }
  26.         for (dutyCycle = 100; dutyCycle >= 0; dutyCycle -= 10) {
  27.             Set_PWM_DutyCycle(dutyCycle);
  28.             HAL_Delay(500);
  29.         }
  30.     }
  31. }

  32. // TIM1初始化函数(由STM32CubeMX生成)
  33. void MX_TIM1_Init(void) {
  34.     TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  35.     TIM_MasterConfigTypeDef sMasterConfig = {0};
  36.     TIM_OC_InitTypeDef sConfigOC = {0};

  37.     htim1.Instance = TIM1;
  38.     htim1.Init.Prescaler = 1700 - 1; // 时钟预分频
  39.     htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  40.     htim1.Init.Period = 1000 - 1; // 设置周期,生成50Hz信号
  41.     htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  42.     htim1.Init.RepetitionCounter = 0;
  43.     htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;

  44.     if (HAL_TIM_Base_Init(&htim1) != HAL_OK) {
  45.         Error_Handler();
  46.     }
  47.     sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  48.     if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) {
  49.         Error_Handler();
  50.     }
  51.     if (HAL_TIM_PWM_Init(&htim1) != HAL_OK) {
  52.         Error_Handler();
  53.     }
  54.     sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  55.     sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  56.     if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) {
  57.         Error_Handler();
  58.     }
  59.     sConfigOC.OCMode = TIM_OCMODE_PWM1;
  60.     sConfigOC.Pulse = 0; // 初始占空比为0
  61.     sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  62.     sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

  63.     if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) {
  64.         Error_Handler();
  65.     }

  66.     HAL_TIM_MspPostInit(&htim1);
  67. }
代码解析
  • PWM初始化通过HAL_TIM_PWM_Start函数启动定时器的PWM功能。
  • 占空比调节使用__HAL_TIM_SET_COMPARE动态设置比较值,从而调整PWM信号的占空比。
  • 延时循环使用HAL_Delay模拟占空比逐步变化的效果,可以用于调光或调速应用。


注意事项
  • 确保使用的引脚支持定时器功能,具体引脚信息可参考STM32G431的引脚分配表。
  • PWM信号的频率由定时器的Prescaler和Period共同决定,确保正确设置以满足应用需求。
  • 如果需要更高的分辨率或更低的频率,可以适当调整定时器参数。

总结通过本文的示例代码,STM32G431可以轻松实现PWM输出,并可根据实际需求动态调整占空比。这种实现方式不仅适用于简单的LED调光,还可以拓展到复杂的电机控制或音频信号生成中。希望这篇文章能够帮助你快速掌握STM32 PWM功能的使用。

公羊子丹 发表于 2024-11-29 07:49 来自手机 | 显示全部楼层
哇,这篇文章太详细了,新手直接跟着做就行!
周半梅 发表于 2024-11-29 07:50 来自手机 | 显示全部楼层
我之前总是搞不清楚占空比怎么调,终于看明白了!
帛灿灿 发表于 2024-11-29 07:50 来自手机 | 显示全部楼层
STM32G431的性能确实强大,学到新技能了。
童雨竹 发表于 2024-11-29 07:50 来自手机 | 显示全部楼层
请问支持多路PWM输出同时运行吗?
万图 发表于 2024-11-29 07:51 来自手机 | 显示全部楼层
我试了一下,发现定时器配置很关键,感谢讲解!
Wordsworth 发表于 2024-11-29 07:51 来自手机 | 显示全部楼层
如果需要更高频率,是不是只能调低Prescaler?
Bblythe 发表于 2024-11-29 07:51 来自手机 | 显示全部楼层
看完文章直接去买了一块STM32G431板子,实战一下!
Uriah 发表于 2024-11-29 07:51 来自手机 | 显示全部楼层
文章写得好通俗易懂,对小白很友好!
Clyde011 发表于 2024-11-29 07:51 来自手机 | 显示全部楼层
感觉如果能配上实际波形截图就更好了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

165

主题

6121

帖子

0

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