PWM 驱动

[English]

概述

PWM(Pulse Width Modulation)脉宽调制是一种通过改变脉冲宽度来控制输出功率的技术,广泛应用于电机控制、LED 调光、音频输出等场景。BK7239N 支持多个 PWM 通道,提供灵活的脉宽调制解决方案。

功能描述

  • 多通道支持:支持多个 PWM 通道同时工作

  • 周期占空比:支持灵活的周期和占空比配置

  • 相移功能:支持多通道相移输出

  • 渐变功能:支持占空比渐变输出

  • 中断支持:支持 PWM 完成中断

  • 频率控制:支持多种频率设置

  • 占空比控制:支持 0-100% 占空比控制

  • 相位控制:支持相位偏移控制

  • 低功耗:支持低功耗模式,节省功耗

开发指引

  1. 初始化流程 - 调用 bk_pwm_driver_init() 初始化 PWM 驱动 - 配置 PWM 参数(周期、占空比、频率等) - 调用 bk_pwm_init() 初始化具体 PWM 通道 - 根据需要配置中断

  2. 基本使用 - 使用 bk_pwm_set_period_duty() 设置周期和占空比 - 使用 bk_pwm_start() 启动 PWM 输出 - 使用 bk_pwm_stop() 停止 PWM 输出 - 使用 bk_pwm_set_duty() 动态调整占空比

  3. 相移功能 - 使用 bk_pwm_phase_shift_init() 初始化相移模式 - 配置多个通道的占空比和相位 - 使用 bk_pwm_phase_shift_start() 启动相移输出

  4. 渐变功能 - 使用 bk_pwm_fade_init() 初始化渐变模式 - 设置渐变参数(起始/结束占空比、渐变时间) - 使用 bk_pwm_fade_start() 启动渐变输出

注意事项

  • 确保在调用其他 PWM API 前先调用 bk_pwm_driver_init()

  • 占空比不能超过周期值

  • 频率设置需要考虑硬件限制

  • 使用中断模式时注意中断优先级设置

  • 注意 PWM 信号线的电气特性

  • 低功耗模式下 PWM 可能被关闭,需要重新初始化

API 说明

主要 API 函数:

  • bk_pwm_driver_init() - 初始化 PWM 驱动

  • bk_pwm_driver_deinit() - 反初始化 PWM 驱动

  • bk_pwm_init() - 初始化 PWM 通道

  • bk_pwm_deinit() - 反初始化 PWM 通道

  • bk_pwm_start() - 启动 PWM 输出

  • bk_pwm_stop() - 停止 PWM 输出

  • bk_pwm_set_period_duty() - 设置周期和占空比

  • bk_pwm_set_duty() - 设置占空比

  • bk_pwm_set_frequency() - 设置频率

  • bk_pwm_set_phase() - 设置相位

  • bk_pwm_phase_shift_init() - 初始化相移模式

  • bk_pwm_phase_shift_start() - 启动相移输出

  • bk_pwm_phase_shift_stop() - 停止相移输出

  • bk_pwm_fade_init() - 初始化渐变模式

  • bk_pwm_fade_start() - 启动渐变输出

  • bk_pwm_fade_stop() - 停止渐变输出

  • bk_pwm_register_isr() - 注册中断服务函数

  • bk_pwm_unregister_isr() - 注销中断服务函数

  • bk_pwm_enable_interrupt() - 启用中断

  • bk_pwm_disable_interrupt() - 禁用中断

示例代码

基本使用示例:

#include <driver/pwm.h>

void pwm_example(void)
{
    pwm_init_config_t config = {
        .period_cycle = 1000,
        .duty_cycle = 500,
        .freq = 1000
    };

    // 初始化 PWM 驱动
    bk_pwm_driver_init();

    // 初始化 PWM 通道 0
    bk_pwm_init(PWM_CHAN_0, &config);

    // 启动 PWM 输出
    bk_pwm_start(PWM_CHAN_0);

    // 动态调整占空比
    bk_pwm_set_duty(PWM_CHAN_0, 750);  // 75% 占空比
}

相移输出示例:

void pwm_phase_shift_example(void)
{
    pwm_phase_shift_config_t config = {
        .psc = 0,
        .period_cycle = 1000,
        .chan_num = 2,
        .duty_config = {
            {.chan = PWM_CHAN_0, .duty_cycle = 300},
            {.chan = PWM_CHAN_1, .duty_cycle = 300}
        }
    };

    // 初始化相移模式
    bk_pwm_phase_shift_init(&config);

    // 启动相移输出
    bk_pwm_phase_shift_start();
}

渐变输出示例:

void pwm_fade_example(void)
{
    pwm_fade_config_t config = {
        .chan = PWM_CHAN_0,
        .start_duty = 0,
        .end_duty = 1000,
        .fade_time_ms = 2000
    };

    // 初始化渐变模式
    bk_pwm_fade_init(&config);

    // 启动渐变输出
    bk_pwm_fade_start(PWM_CHAN_0, PWM_DUTY_DIR_INCREASE);
}

中断处理示例:

static void pwm_interrupt_handler(pwm_chan_t chan, void *param)
{
    printf("PWM channel %d interrupt\n", chan);
}

void pwm_interrupt_example(void)
{
    // 注册中断服务函数
    bk_pwm_register_isr(PWM_CHAN_0, pwm_interrupt_handler, NULL);

    // 启用中断
    bk_pwm_enable_interrupt(PWM_CHAN_0);
}

多通道控制示例:

void pwm_multi_channel_example(void)
{
    // 初始化多个通道
    pwm_init_config_t config = {
        .period_cycle = 1000,
        .duty_cycle = 500,
        .freq = 1000
    };

    bk_pwm_init(PWM_CHAN_0, &config);
    bk_pwm_init(PWM_CHAN_1, &config);
    bk_pwm_init(PWM_CHAN_2, &config);

    // 启动所有通道
    bk_pwm_start(PWM_CHAN_0);
    bk_pwm_start(PWM_CHAN_1);
    bk_pwm_start(PWM_CHAN_2);

    // 分别设置不同的占空比
    bk_pwm_set_duty(PWM_CHAN_0, 250);  // 25%
    bk_pwm_set_duty(PWM_CHAN_1, 500);  // 50%
    bk_pwm_set_duty(PWM_CHAN_2, 750);  // 75%
}

常见问题

  • PWM 输出不正确:检查周期和占空比设置、频率配置

  • 相移不工作:确认相移配置、通道数量、占空比设置

  • 渐变不平滑:调整渐变时间、起始/结束占空比

  • 中断未触发:确认中断注册和启用,检查中断优先级设置

实战示例

  1. 多通道相移输出

pwm_phase_shift_config_t sc = {
    .psc = 0,
    .period_cycle = 1000,
    .chan_num = 2,
    .duty_config = {
        { .chan = PWM_CH0, .duty_cycle = 300 },
        { .chan = PWM_CH1, .duty_cycle = 300 },
    },
};
bk_pwm_phase_shift_init(&sc);
bk_pwm_phase_shift_start();

常见错误码说明

  • BK_ERR_PWM_PERIOD_DUTY:占空或周期配置非法

  • BK_ERR_PWM_PHASE_SHIFT_CHAN_NUM:相移模式通道数不足

  • BK_ERR_NO_MEM:相移配置缓存分配失败