打印
[STM32G4]

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

[复制链接]
31|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信号的完整代码,支持动态调整占空比:
#include "main.h"

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

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

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

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

    PWM_Init(); // 启动PWM

    while (1) {
        // 动态调节占空比
        for (dutyCycle = 0; dutyCycle <= 100; dutyCycle += 10) {
            Set_PWM_DutyCycle(dutyCycle);
            HAL_Delay(500); // 每500ms调整一次
        }
        for (dutyCycle = 100; dutyCycle >= 0; dutyCycle -= 10) {
            Set_PWM_DutyCycle(dutyCycle);
            HAL_Delay(500);
        }
    }
}

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

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

    if (HAL_TIM_Base_Init(&htim1) != HAL_OK) {
        Error_Handler();
    }
    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
    if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) {
        Error_Handler();
    }
    if (HAL_TIM_PWM_Init(&htim1) != HAL_OK) {
        Error_Handler();
    }
    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) {
        Error_Handler();
    }
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 0; // 初始占空比为0
    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_MspPostInit(&htim1);
}
代码解析
  • 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的性能确实强大,学到新技能了。

使用特权

评论回复
5
童雨竹| | 2024-11-29 07:50 | 只看该作者
请问支持多路PWM输出同时运行吗?

使用特权

评论回复
6
万图| | 2024-11-29 07:51 | 只看该作者
我试了一下,发现定时器配置很关键,感谢讲解!

使用特权

评论回复
7
Wordsworth| | 2024-11-29 07:51 | 只看该作者
如果需要更高频率,是不是只能调低Prescaler?

使用特权

评论回复
8
Bblythe| | 2024-11-29 07:51 | 只看该作者
看完文章直接去买了一块STM32G431板子,实战一下!

使用特权

评论回复
9
Uriah| | 2024-11-29 07:51 | 只看该作者
文章写得好通俗易懂,对小白很友好!

使用特权

评论回复
10
Clyde011| | 2024-11-29 07:51 | 只看该作者
感觉如果能配上实际波形截图就更好了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

31

主题

3610

帖子

0

粉丝