[STM32G4] 使用STM32G431实现PWM输出详解

[复制链接]
2718|9
 楼主| Clyde011 发表于 2024-12-5 15:08 | 显示全部楼层 |阅读模式
在嵌入式开发中,PWM(脉宽调制)是一种常用技术,用于生成模拟信号、控制电机、LED亮度等。本文以STM32G431为例,详细讲解如何通过TIM1定时器实现PWM输出,包含完整代码和关键点分析。
一、项目需求目标是使用STM32G431生成两路独立的PWM信号,分别控制LED亮度和直流电机速度:
  • PWM频率为1kHz。
  • 占空比可动态调整(0%-100%)。
  • 使用DMA更新占空比,减小CPU负担。
二、硬件准备
  • STM32G431开发板
  • 一颗LED
  • 一台直流电机和驱动电路
  • 电源及相关连接线
三、软件开发开发工具:STM32CubeMX、Keil MDK(或其他支持的IDE)。
1. 定时器配置在STM32CubeMX中:
  • 启用TIM1定时器,设置为PWM模式。
  • 选择两个通道(CH1和CH2)。
  • 设定时钟频率和计数器周期,以实现1kHz频率。
  • 配置DMA通道用于动态更新占空比。
2. 配置代码实现以下是基于STM32 HAL库的完整实现代码:
  1. #include "main.h"

  2. /* 定义全局变量 */
  3. TIM_HandleTypeDef htim1;
  4. DMA_HandleTypeDef hdma_tim1_ch1;
  5. DMA_HandleTypeDef hdma_tim1_ch2;

  6. /* PWM占空比缓冲区 */
  7. uint32_t pwm_duty_cycle[2] = {50, 75};  // 初始占空比分别为50%和75%

  8. /* 初始化TIM1定时器 */
  9. void TIM1_PWM_Init(void) {
  10.     TIM_OC_InitTypeDef sConfigOC = {0};
  11.    
  12.     htim1.Instance = TIM1;
  13.     htim1.Init.Prescaler = 80 - 1;  // 时钟分频
  14.     htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  15.     htim1.Init.Period = 1000 - 1;  // 计数周期,1kHz
  16.     htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  17.     htim1.Init.RepetitionCounter = 0;
  18.     HAL_TIM_PWM_Init(&htim1);

  19.     sConfigOC.OCMode = TIM_OCMODE_PWM1;
  20.     sConfigOC.Pulse = 500;  // 初始占空比50%
  21.     sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  22.     sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

  23.     /* 配置通道1 */
  24.     HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);
  25.     /* 配置通道2 */
  26.     HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2);
  27. }

  28. /* 初始化DMA */
  29. void DMA_Init(void) {
  30.     __HAL_RCC_DMA1_CLK_ENABLE();
  31.    
  32.     /* 配置DMA用于TIM1通道1 */
  33.     hdma_tim1_ch1.Instance = DMA1_Channel1;
  34.     hdma_tim1_ch1.Init.Direction = DMA_MEMORY_TO_PERIPH;
  35.     hdma_tim1_ch1.Init.PeriphInc = DMA_PINC_DISABLE;
  36.     hdma_tim1_ch1.Init.MemInc = DMA_MINC_ENABLE;
  37.     hdma_tim1_ch1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  38.     hdma_tim1_ch1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
  39.     hdma_tim1_ch1.Init.Mode = DMA_CIRCULAR;
  40.     hdma_tim1_ch1.Init.Priority = DMA_PRIORITY_HIGH;
  41.     HAL_DMA_Init(&hdma_tim1_ch1);
  42.     __HAL_LINKDMA(&htim1, hdma[TIM_DMA_ID_CC1], hdma_tim1_ch1);

  43.     /* 配置DMA用于TIM1通道2 */
  44.     hdma_tim1_ch2.Instance = DMA1_Channel2;
  45.     HAL_DMA_Init(&hdma_tim1_ch2);
  46.     __HAL_LINKDMA(&htim1, hdma[TIM_DMA_ID_CC2], hdma_tim1_ch2);
  47. }

  48. /* 启动PWM */
  49. void Start_PWM(void) {
  50.     HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_1, &pwm_duty_cycle[0], 1);
  51.     HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_2, &pwm_duty_cycle[1], 1);
  52. }

  53. /* 主函数 */
  54. int main(void) {
  55.     HAL_Init();
  56.     SystemClock_Config();  // 时钟配置
  57.     TIM1_PWM_Init();
  58.     DMA_Init();
  59.     Start_PWM();

  60.     while (1) {
  61.         /* 动态调整占空比 */
  62.         pwm_duty_cycle[0] = (pwm_duty_cycle[0] + 10) % 100;
  63.         pwm_duty_cycle[1] = (pwm_duty_cycle[1] + 20) % 100;
  64.         HAL_Delay(500);  // 模拟任务处理
  65.     }
  66. }
四、关键代码讲解
  • 定时器初始化
    通过设置预分频器和计数周期,定时器被配置为1kHz的PWM输出,通道1和通道2分别控制LED和电机。
  • DMA与PWM结合
    利用DMA循环模式,每500ms更新占空比,无需占用CPU资源。
  • 动态调节占空比
    主循环中简单模拟占空比变化,真实项目可结合传感器数据或用户输入调整。

五、运行效果烧录代码后,LED亮度和电机转速会以不同的规律动态变化。
六、总结本文展示了使用STM32G431通过定时器和DMA生成PWM信号的完整流程。这种方法广泛适用于对功率设备的控制,如LED调光、电机驱动等。如果对某些细节有疑问,欢迎在评论区留言讨论!




公羊子丹 发表于 2024-12-5 15:08 | 显示全部楼层
看得很清楚,这个PWM配置我也试试在自己的项目里用!
周半梅 发表于 2024-12-5 15:08 | 显示全部楼层
最近刚好在调STM32的PWM,DMA结合确实是个高效方法!
帛灿灿 发表于 2024-12-5 15:09 | 显示全部楼层
不错的文章,感觉直接抄代码就能跑了哈哈。
童雨竹 发表于 2024-12-5 15:09 | 显示全部楼层
TIM1的用法讲得很详细,帮大忙了!
万图 发表于 2024-12-5 15:09 | 显示全部楼层
能再分享一下如何用CubeMX快速配置吗?想更深入学学。
Pulitzer 发表于 2024-12-5 15:09 | 显示全部楼层
文章写得挺通俗易懂,尤其是占空比动态调节部分!
Wordsworth 发表于 2024-12-5 15:10 | 显示全部楼层
好东西,感觉这个代码能直接套用到多轴控制上!
Bblythe 发表于 2024-12-5 15:10 | 显示全部楼层
PWM生成模拟信号这块可以用DAC代替吗?期待后续讲解!
Uriah 发表于 2024-12-5 15:10 | 显示全部楼层
有点意思,开发电机控制这块确实离不开定时器。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

185

主题

6260

帖子

0

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