打印
[STM32G4]

使用STM32G431实现PWM信号的精确控制

[复制链接]
710|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Clyde011|  楼主 | 2024-12-15 07:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在嵌入式系统中,PWM(脉宽调制)信号常用于控制电机速度、调节LED亮度等场景。本文将以STM32G431微控制器为例,详细讲解如何配置TIM1定时器生成PWM信号,并通过调整占空比实现精确控制。
STM32G431简介STM32G431是ST公司推出的一款功能强大的32位微控制器,基于Cortex-M4内核,主频高达170 MHz。它内置多个高级定时器(如TIM1),支持高分辨率的PWM输出,非常适合电机控制、工业自动化和其他实时应用。
PWM信号生成原理PWM信号通过固定频率的方波控制信号强度,其占空比(即高电平持续时间与整个周期的比值)决定了输出的平均功率。例如,50%占空比表示输出信号的高低电平时间相等,而25%占空比表示高电平时间仅为整个周期的四分之一。
开发环境准备
  • STM32CubeIDE(用于编写代码和调试)。
  • STM32G431开发板。
  • 一个PWM信号测试设备(如LED或示波器)。
硬件连接将一个LED连接到开发板的PWM引脚(例如PA8),并在电路中串联一个限流电阻(如220欧姆)。
软件实现以下代码实现了使用TIM1定时器生成PWM信号,并通过调整占空比控制LED的亮度。
#include "stm32g4xx_hal.h"

// 定时器句柄
TIM_HandleTypeDef htim1;

// 初始化定时器
void TIM1_Init(void) {
    __HAL_RCC_TIM1_CLK_ENABLE();
    htim1.Instance = TIM1;
    htim1.Init.Prescaler = 170 - 1; // 定时器预分频值
    htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim1.Init.Period = 1000 - 1; // PWM周期1000个计数
    htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
    HAL_TIM_PWM_Init(&htim1);

    // 配置PWM输出通道
    TIM_OC_InitTypeDef sConfigOC;
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 500; // 初始占空比为50%
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
    HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);

    // 启动PWM
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
}

// 初始化GPIO
void GPIO_Init(void) {
    __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = GPIO_PIN_8; // TIM1_CH1引脚
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

// 修改占空比
void Set_PWM_DutyCycle(uint16_t dutyCycle) {
    if (dutyCycle <= 1000) { // 确保占空比值合法
        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, dutyCycle);
    }
}

int main(void) {
    HAL_Init();
    SystemClock_Config();
    GPIO_Init();
    TIM1_Init();

    while (1) {
        for (uint16_t duty = 0; duty <= 1000; duty += 10) {
            Set_PWM_DutyCycle(duty); // 增加占空比
            HAL_Delay(50);
        }
        for (uint16_t duty = 1000; duty > 0; duty -= 10) {
            Set_PWM_DutyCycle(duty); // 减小占空比
            HAL_Delay(50);
        }
    }
}
代码解析
  • TIM1_Init函数:初始化TIM1定时器并配置PWM模式。
  • Set_PWM_DutyCycle函数:通过修改TIM1的比较寄存器(CCR1),动态调整PWM占空比。
  • 主循环:实现占空比在0%到100%之间的循环渐变,从而让LED的亮度逐渐变化。
测试与优化
  • 使用示波器测试PA8引脚的PWM输出信号,观察占空比是否随代码变化。
  • 如果需要更高的分辨率,可以调整Prescaler和Period参数,使PWM周期更精确。
小结通过STM32G431和其高级定时器TIM1,我们可以轻松生成高精度的PWM信号,并灵活调整占空比。这种方法广泛适用于工业控制、电机驱动和信号调制等场景。

使用特权

评论回复
沙发
公羊子丹| | 2024-12-15 07:56 | 只看该作者
看起来很详细,正好最近在学习STM32的定时器,受教了。

使用特权

评论回复
板凳
周半梅| | 2024-12-15 07:56 | 只看该作者
有没有遇到初始化失败的情况?想了解一下调试经验。

使用特权

评论回复
地板
帛灿灿| | 2024-12-15 07:56 | 只看该作者
PWM输出能支持多高的频率?对实际应用有些好奇。

使用特权

评论回复
5
童雨竹| | 2024-12-15 07:57 | 只看该作者
LED亮度变化很流畅,这种代码结构很实用!

使用特权

评论回复
6
万图| | 2024-12-15 07:57 | 只看该作者
你觉得用STM32G4控制电机和用G0系列有什么主要区别?

使用特权

评论回复
7
Wordsworth| | 2024-12-15 07:58 | 只看该作者
如果换成其他定时器,比如TIM2,是不是改一下引脚和时钟就可以了?

使用特权

评论回复
8
Bblythe| | 2024-12-15 07:58 | 只看该作者
定时器初始化这块代码很经典,感觉可以直接用到很多项目中。

使用特权

评论回复
9
Pulitzer| | 2024-12-15 07:58 | 只看该作者
想了解更多关于STM32CubeMX生成代码的方式,能否再写一篇?

使用特权

评论回复
10
Uriah| | 2024-12-15 07:59 | 只看该作者
G4系列的PWM精度真不错,支持!

使用特权

评论回复
11
Amazingxixixi| | 2024-12-27 16:55 | 只看该作者
过来学习学习

使用特权

评论回复
12
Stahan| | 2024-12-29 21:40 | 只看该作者
G4是专门做电机控制的吗

使用特权

评论回复
13
是你的乱码| | 2024-12-31 00:32 | 只看该作者

通过调整占空比来控制 LED 亮度

通过调整占空比来控制 LED 亮度

使用特权

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

本版积分规则

33

主题

3484

帖子

0

粉丝