首页 虚拟现实

GD32 RISC-V PWM 输出:驱动电机、呼吸灯与音阶的实战解析

分类:虚拟现实
字数: (2010)
阅读: (8675)
内容摘要:GD32 RISC-V PWM 输出:驱动电机、呼吸灯与音阶的实战解析,

在嵌入式系统开发中,PWM(脉冲宽度调制)输出是极其常用且重要的外设功能。无论是控制电机转速、调节 LED 灯亮度、甚至生成简单的音频,都离不开 PWM 的身影。本文将以《嵌入式 – GD32开发实战指南(RISC-V版本)》第8章为基础,深入探讨 GD32 RISC-V 系列单片机的 PWM 输出实现,并通过实战案例,帮助读者掌握其核心原理和应用技巧。

PWM 基础原理回顾

PWM 的核心在于通过改变脉冲的占空比(高电平时间在一个周期内的占比),从而改变输出的平均电压或电流。例如,在控制 LED 亮度时,占空比越大,LED 就越亮。PWM 的频率决定了信号的刷新速度,过低的频率可能会导致 LED 闪烁或电机抖动。

GD32 RISC-V 单片机通常具有多个定时器,每个定时器可以配置成 PWM 输出模式。定时器的计数器决定了 PWM 的频率,而比较寄存器(Capture Compare Register, CCR)则决定了 PWM 的占空比。

GD32 RISC-V PWM 输出:驱动电机、呼吸灯与音阶的实战解析

GD32 RISC-V PWM 输出的配置步骤

  1. 使能定时器时钟和 GPIO 时钟:首先需要使能定时器和对应 GPIO 的时钟。这可以通过 GD32 的 RCC(Reset and Clock Control)模块来实现。

  2. 配置 GPIO 为复用功能:将 GPIO 配置为定时器的 PWM 输出功能,这通常涉及到配置 GPIO 的 Alternate Function(AF)模式。GD32 的 GPIO 复用功能需要查找芯片的数据手册,确定哪个 AF 功能对应于哪个定时器通道。

    GD32 RISC-V PWM 输出:驱动电机、呼吸灯与音阶的实战解析
  3. 配置定时器基本参数:配置定时器的 prescaler(预分频器)和 period(周期),从而确定 PWM 的频率。PWM 频率的计算公式为:PWM 频率 = 系统时钟频率 / (Prescaler + 1) / (Period + 1)

  4. 配置 PWM 输出通道参数:配置定时器的比较寄存器(CCR),从而确定 PWM 的占空比。占空比的计算公式为:占空比 = CCR / (Period + 1)。还需要配置 PWM 的极性(高电平有效还是低电平有效)和输出模式(例如 PWM1 模式或 PWM2 模式)。

    GD32 RISC-V PWM 输出:驱动电机、呼吸灯与音阶的实战解析
  5. 使能定时器 PWM 输出:最后,使能定时器的 PWM 输出功能,使能相应的通道输出。同时,也要确保定时器的主输出使能位(MOE)被置位。

代码示例:呼吸灯效果

以下是一个简单的 GD32 RISC-V PWM 实现呼吸灯效果的代码示例(基于GD32VF103):

GD32 RISC-V PWM 输出:驱动电机、呼吸灯与音阶的实战解析
#include "gd32vf103.h"
#include <stdio.h>

#define LED_PIN GPIO_PIN_13 // 连接 LED 的 GPIO 引脚
#define LED_PORT GPIOC       // 连接 LED 的 GPIO 端口

void rcu_config(void) {
    rcu_periph_clock_enable(RCU_GPIOC); // 使能 GPIOC 时钟
    rcu_periph_clock_enable(RCU_TIMER2); // 使能 TIMER2 时钟
}

void gpio_config(void) {
    gpio_init(LED_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, LED_PIN); // 配置 GPIO 为复用推挽输出
    gpio_pin_remap_config(GPIO_TIMER2_CH2_FULL_REMAP,ENABLE); // GD32VF103需要重映射
}

void timer_config(void) {
    timer_parameter_struct timer_initpara;
    timer_oc_parameter_struct timer_ocinitpara;

    /* 初始化 TIMER2 */
    timer_deinit(TIMER2);

    /* TIMER2 配置 */
    timer_initpara.prescaler         = 71; // 72MHz / (71+1) = 1MHz
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;  // 边缘对齐模式
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;   // 向上计数
    timer_initpara.period            = 999; // 1ms 周期
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;  // 时钟分频
    timer_initpara.repetitioncounter = 0;    // 重复计数器
    timer_init(TIMER2, &timer_initpara);

    /* 配置 TIMER2 CH2 为 PWM 输出 */
    timer_ocinitpara.outputstate  = TIMER_CCX_ENABLE;  // 使能通道输出
    timer_ocinitpara.outputnstate = TIMER_CCXN_DISABLE; // 禁止互补通道输出
    timer_ocinitpara.ocmode       = TIMER_OC_MODE_PWM0;   // PWM 模式 1
    timer_ocinitpara.ocpolarity   = TIMER_OC_POLARITY_HIGH; // 高电平有效
    timer_ocinitpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
    timer_ocinitpara.ocidlemask   = TIMER_IDLE_MASK_LOW;
    timer_ocinitpara.ocnidlemask  = TIMER_IDLE_MASK_LOW;
    timer_channel_output_config(TIMER2, TIMER_CH_2, &timer_ocinitpara);

    timer_channel_output_pulse_value_config(TIMER2, TIMER_CH_2, 0); // 初始占空比为 0
    timer_enable(TIMER2); // 使能定时器
    timer_channel_output_shadow_config(TIMER2, TIMER_CH_2, TIMER_OC_SHADOW_DISABLE); //不使用影子寄存器
    timer_primary_output_config(TIMER2,ENABLE); // 使能主输出
}

void delay(uint32_t time) {
    uint32_t i;
    for (i = 0; i < time; i++);
}

int main(void) {
    rcu_config();
    gpio_config();
    timer_config();

    uint16_t duty_cycle = 0;
    int8_t direction = 1; // 1 表示增加,-1 表示减少

    while (1) {
        timer_channel_output_pulse_value_config(TIMER2, TIMER_CH_2, duty_cycle);

        if (direction == 1) {
            duty_cycle++;
            if (duty_cycle > 999) {
                direction = -1;
            }
        } else {
            duty_cycle--;
            if (duty_cycle == 0) {
                direction = 1;
            }
        }
        delay(10000); // 调整延时来控制呼吸速度
    }
}

实战避坑经验

  • GPIO 复用功能选择错误:GD32 的 GPIO 复用功能众多,一定要仔细查阅数据手册,选择正确的 AF 功能,否则 PWM 输出无法正常工作。
  • 定时器时钟配置错误:定时器的时钟源和预分频器配置错误会导致 PWM 频率不正确,影响控制效果。要仔细计算和验证 PWM 频率。
  • PWM 极性配置错误:PWM 的极性决定了高电平对应的是导通还是截止。配置错误会导致控制逻辑反转,例如 LED 亮度和占空比的关系反转。
  • 中断优先级配置不当:如果 PWM 输出需要配合中断使用,一定要合理配置中断优先级,避免中断冲突导致系统异常。
  • 调试工具选择:使用 J-Link 或 ST-Link 等调试器,可以方便地在线调试 PWM 输出,观察 PWM 信号的波形和占空比,从而快速定位问题。配合诸如 Saleae Logic Analyzer 这样的逻辑分析仪,可以更精确地分析 PWM 信号。

总结

本文以《嵌入式 – GD32开发实战指南(RISC-V版本)》第8章为基础,详细介绍了 GD32 RISC-V 单片机 PWM 输出的实现方法,并提供了呼吸灯效果的实战案例。掌握 PWM 输出技术,能够为嵌入式系统的开发提供强大的控制能力。希望读者在实际项目中灵活运用,创造出更多有趣的应用。

GD32 RISC-V PWM 输出:驱动电机、呼吸灯与音阶的实战解析

转载请注明出处: 代码老中医

本文的链接地址: http://m.acea4.store/blog/508169.SHTML

本文最后 发布于2026-04-09 18:49:03,已经过了18天没有更新,若内容或图片 失效,请留言反馈

()
您可能对以下文章感兴趣
评论
  • 卷王来了 4 天前
    GPIO复用功能选择真的很容易出错,经常对着手册查半天。感谢作者的提醒。
  • 太阳当空照 3 天前
    写的很详细,赞一个!正好在用GD32做电机控制,这个呼吸灯的例子可以借鉴一下。
  • 干饭人 5 天前
    逻辑分析仪是神器啊!之前调试PWM信号,没有逻辑分析仪,真是太痛苦了。