PWM

1. PWM驱动说明

1.1 简介

PWM(脉冲宽度调制)应用场景广泛,思澈平台支持输出PWM的定时器类型包括 GPTIM(通用定时器)ATIM(高级定时器)LPTIM(低功耗定时器),其中GPTIM PWM因通用性强,优先推荐使用。

1.1.1 PWM列表及归属核

平台

HCPU

LCPU

52x

PWM 2、PWM 3、PWM A1、PWM LPTIM1

PWM 4、PWM 5、PWM 6、PWM LPTIM2、PWM LPTIM3

56x

PWM 2、PWM 3、PWM A1、PWM LPTIM1

PWM 4、PWM 5、PWM 6、PWM LPTIM2、PWM LPTIM3

55x

PWM 2、PWM 3、PWM LPTIM1

PWM 4、PWM 5、PWM 6、PWM LPTIM2、PWM LPTIM3

58x

PWM 2、PWM 3、PWM A1、PWM A2、PWM LPTIM1

PWM 4、PWM 5、PWM 6、PWM LPTIM2、PWM LPTIM3

备注

PWM 2~PWM 6: 与GPTIM存在固定对应关系

  • PWM 2对应GPTIM1、

  • PWM 3对应GPTIM2

  • PWM 6对应GPTIM5

1.2 PWM在52x/55x/56x/58x的差异

不同系列芯片的PWM特性存在两点核心差异,需根据具体型号针对性配置:

1.2.1 IO口灵活性差异

  • 55x/58x系列:输出PWM的IO口为固定分配,需参考芯片规格书确认具体IO对应的PWM通道,不可随意切换;

  • 52x/56x系列:灵活性更高,任何带有TIM(定时器)功能的IO,均可通过配置映射为任意一种PWM输出,无需受固定通道限制。

规格对比参考图:

../../_images/PWM_IO.png

1.2.2 HCPU 自动降频的影响

当系统宏 BSP_PM_FREQ_SCALING 开启时,HCPU(大核)会根据系统负载自动降低运行主频以节省功耗。此机制会间接影响 HCPU 管辖的 IO 输出的 PWM 频率——由于 PWM 时钟源与 HCPU 主频关联,主频降低时,PWM 频率会同步下降,可能导致依赖稳定频率的设备(如马达、背光)工作异常。

针对不同芯片系列,解决方案如下:

  • 55x/56x/58x 系列
    优先选择 LCPU(小核)的 IO 输出 PWM。LCPU 的 PWM 时钟源独立于 HCPU 主频,频率不受 HCPU 降频影响,可保证输出稳定。
    若因硬件限制必须使用 HCPU 的 IO,需关闭宏 BSP_PM_FREQ_SCALING(关闭自动降频),但此操作会导致亮屏等场景下功耗升高。

  • 52x 系列
    若使用 HCPU 的 IO 输出 PWM,建议优先选择 GPTIM2 对应的 PWM。GPTIM2 的时钟源设计特殊,不受系统主频变化影响,可在 HCPU 降频时保持 PWM 频率稳定。

1.3 PWM DMA

PWM DMA可用于把数据从内存搬运到CCR寄存器,实现周期不变的情况,自动改变占空比;
DMA触发方式及说明:

方式

触发源

PWM_UPDATE_DMA

AAR 和CCR 都触发

PWM_CCX_DMA

只有CCX 触发

典型的应用:PWM DMA 模拟单线SID协议来驱动 RGBLED;

1.4 PWM的使用

PWM的使用需经过配置选型、硬件绑定、参数设置和驱动调用四个核心步骤,以下为详细说明:

1.4.2 配置 Pinmux(绑定 IO 与 PWM 通道)

Pinmux 配置的核心作用是建立物理 IO 引脚与目标 PWM 通道的硬件映射关系,告知芯片“哪个 IO 负责输出哪个 PWM 信号”。只有完成绑定,PWM 定时器产生的波形才能通过指定 IO 输出到外部设备(如马达、背光电路)。

  • 配置逻辑与示例 以“PA20 引脚使用 PWM2(对应 GPTIM2_CH1 通道)”为例,配置代码如下:

// 函数:HAL_PIN_Set(引脚标识, 功能别名, 上下拉配置, 功能使能)
HAL_PIN_Set(
    PAD_PA20,       // 物理 IO 引脚(如 PA20)
    GPTIM2_CH1,     // PWM 通道(PWM2 对应 GPTIM1,此处 GPTIM2_CH1 对应 PWM3的通道1,需按实际映射调整)
    PIN_NOPULL,     // 上下拉配置(PWM 输出一般无需上下拉,避免信号冲突)
    1               // 1:引脚位于HCPU;0:引脚位于LCPU
);

1.4.3 配置应用的PWM参数

在应用层配置PWM的通道、周期(频率)、占空比等参数,适配目标设备(如马达)。以“马达使用PA20作为PWM(GPTIM2)的通道1”为例,配置界面如下:

../../_images/PWM_MOTOR.png

1.4.4 调用PWM驱动接口

通过RT-Thread接口完成PWM初始化与控制,核心流程如下:

../../_images/PWM_USE_FLOW.png

参考代码:

// 查找PWM设备("pwm2"对应GPTIM1)
struct rt_device_pwm *pwm_device = (struct rt_device_pwm *)rt_device_find("pwm2");
// 设置参数(通道1,周期period,占空比pulse)
rt_pwm_set(pwm_device, 1, period, pulse);
// 使能输出
rt_pwm_enable(pwm_device, 1);
// (按需)禁用输出
// rt_pwm_disable(pwm_device, 1);

PWM通道复用规则(避免冲突):

  1. 同一PWM的不同通道,可输出相同频率、不同占空比的波形(如马达和光感可共用同一PWM的不同通道);

  2. 同一PWM的不同通道若频率不同,需确保设备分时使用(如马达和蜂鸣器不同时工作),否则会相互干扰;

  3. 需持续工作且频率不同的设备(如背光),需单独分配PWM,不可复用。

1.5 PWM 停止后的电平控制

PWM停止是指PWM不再输出波形,而保持为低电平或高电平状态。

  • 一般情况下,rt_pwm_disable执行后,PWM通道处于高阻状态,电平无法立刻到低电平,波形如下:

../../_images/PWM_stop0.png
  • 若需实现 “停止后固定电平”(如下方波形),可通过配置占空比实现:

../../_images/PWM_stop1.png

可通过配置占空比为0的方式实现。

备注

  • 配置占空比为0% → 输出低电平

  • 配置占空比为100% → 输出高电平

2 PWM 应用案例

2.1 如何添加一个PWM马达

添加PWM马达的步骤如下:

2.1.2 配置pinmux及使能PWM设备

  • 配置马达对应的pinmux,绑定物理引脚与PWM通道;

 HAL_PIN_Set(PAD_PA20, GPTIM2_CH1, PIN_NOPULL, 1);  //配置PA20为PWM3 Channel1
  • 确认PWM设备处于使能状态。

../../_images/PWM_motor_PA20_config.png

2.1.3 调用应用层接口

Solution封装了以下应用层接口:

接口函数

功能说明

motor_power_on

马达初始化(电源使能)

motor_start

马达开启(默认配置)

motor_stop

马达停止

app_motor_get_level

获取当前占空比

app_motor_set_level

设置占空比

一般使用流程:
motor_power_onmotor_startmotor_stop

修改占空比:
app_motor_set_level

备注

硬件支持实时修改占空比,无需先停止马达再调整,可提高占空比平滑性,避免蜂鸣器等器件切换时的噪声。

2.2如何实现LCD背光使用PWM

LCD背光使用PWM的步骤如下:

2.2.1 修改LCD的Kconfig文件

打开文件\solution2_0\sdk\customer\boards\Kconfig_lcd,找到对应的LCD配置,添加支持PWM背光的代码:

../../_images/LCD_PWM_EN.png

2.2.2 修改Board的Kconfig文件

eh_lb523为例,修改对应开发板下的Kconfig文件,配置背光PWM参数:

../../_images/LCD_PWM_CONFIG.png

2.2.3 确认pinmux与PWM使能

  • 确保背光使用的PWM引脚已正确配置pinmux;

HAL_PIN_Set(PAD_PA01, GPTIM2_CH4, PIN_NOPULL, 1);;  //LCD 一般使用PA01 配置PWM3 Channel4
  • 确认PWM设备处于使能状态。

../../_images/PWM_motor_PA20_config.png

2.2.4 添加背光亮度控制代码

在LCD的背光接口中,增加使用PWM调整亮度的逻辑,参考代码:

void  xxx_SetBrightness(LCDC_HandleTypeDef *hlcdc, uint8_t br)
{
    rt_device_t device = rt_device_find("lcdlight");
    if (device)
    {
        rt_err_t err = rt_device_open(device, RT_DEVICE_OFLAG_RDWR);
        uint8_t val = br;
        rt_device_write(device, 0, &val, 1);
        rt_device_close(device);
    }
    else
    {
        LOG_E("Can't find device lcdlight!");
    }
    LOG_I("XXX_SetBrightness\r\n");
}

若LCD驱动运行在HCPU,而背光PWM使用LCPU的IO,需修改 drv_common.c 中的 HAL_RCC_MspInit() 函数,注释掉背光PWM对应的RCC_Module,避免资源冲突,界面如下:

../../_images/LCD_PWM_MSP_INIT.png

2.3 LPTIM3 在睡眠后继续输出PWM

睡眠状态下输出PWM,需依赖LCPU的LPTIM3(低功耗定时器),配置步骤如下:

2.3.2 配置 LPTIM3 对应的 Pinmux

LPTIM3 常用 IO 为 PB43~PB46,以 PB44 为例,配置代码如下:

// 1. 绑定PB44与LPTIM3_OUT,无上下拉,使能功能
HAL_PIN_Set(PAD_PB44, LPTIM3_OUT, PIN_NOPULL, 0);
// 2. 配置PB44的MUX选择LPTIM3输出
MODIFY_REG(hwp_lpsys_aon->DBGMUX, LPSYS_AON_DBGMUX_PB44_SEL_Msk,
           MAKE_REG_VAL(1, LPSYS_AON_DBGMUX_PB44_SEL_Msk, LPSYS_AON_DBGMUX_PB44_SEL_Pos));

2.3.3 使能睡眠输出宏

在 menuconfig 中勾选宏 PM_WAKEUP_PIN_AS_OUTPUT_IN_SLEEP,确保唤醒源 IO 在睡眠时可继续输出 PWM,界面如下:

../../_images/PWM_LPTIM3_SLEEP.png

注意

  • PM_WAKEUP_PIN_AS_OUTPUT_IN_SLEEP 对所有唤醒源IO生效,需确保其他PB唤醒IO在硬件上已固定上下拉(避免睡眠时漏电)。

2.3.4 调用 LPTIM3 PWM 接口

参考代码如下:

// 查找LPTIM3 PWM设备("pwmlp3"为LPTIM3的设备名)
struct rt_device_pwm *pwm_device = (struct rt_device_pwm *)rt_device_find("pwmlp3");
// 设置PWM参数(通道1,周期period,脉冲宽度pulse)
rt_pwm_set(pwm_device, 1, period, pulse);
// 使能PWM输出(睡眠时持续生效)
rt_pwm_enable(pwm_device, 1);

2.4 RGBLED 使用PWM

RGBLED 会用到PWM DMA 功能,需要确保RGBLED使用的IO 具备PWM DMA功能;
以pwm2 channel1 使用update DMA的方式实现RGBLED的驱动;

2.4.1 menuconfig配置目标PWM

在系统配置界面(menuconfig)中,勾选需要使用的PWM型号(参考PWM列表),确保对应定时器资源被使能。配置界面示例如下:

../../_images/pwm2_ch1_dma_update.png

2.4.2 配置 Pinmux(绑定PA32 到 PWM2 channel1)

以“PA32 引脚使用 PWM2(对应 GPTIM2_CH1 通道)”为例,配置代码如下:

// 函数:HAL_PIN_Set(引脚标识, 功能别名, 上下拉配置, 功能使能)
HAL_PIN_Set(
    PAD_PA32,       // 物理 IO 引脚(如 PA20)
    GPTIM2_CH1,     // PWM 通道(PWM2 对应 GPTIM1,此处 GPTIM2_CH1 对应 PWM3的通道1,需按实际映射调整)
    PIN_NOPULL,     // 上下拉配置(PWM 输出一般无需上下拉,避免信号冲突)
    1               // 1:引脚位于HCPU;0:引脚位于LCPU
);

2.4.3 配置RGBLED的PWM参数

以“RGBLED使用PA32作为PWM(GPTIM2)的通道1”为例,配置界面如下:

../../_images/rgbled_pwm2_channel1_dma.png

2.4.4 调用应用层接口

RGBLED 的rt device 名称为"rgbled";

一般使用流程:
rt_device_find()→ rt_device_control(rgbled_device, PWM_CMD_SET_COLOR, &configuration)