PWM使用参考


REVISION HISTORY

Revision No.
Description
Date
1.0
  • Initial release
  • 08/23/2024

    1. 概述

    PWM (Pulse Width Modulation) 模块用于产生脉宽波形,可通过改变频率和占空比来改变输出的电流、电压进而实现控制电机转速、液晶屏调光等功能;SigmaStar的PWM模块同时具备Group功能(细分为sync 、round、hold、stop),即每4个channel的PWM可绑定成一组,实现4路PWM同步产生或停止。


    2. 功能描述

    • 支持PWM的channel数量为11个,支持加入各自的Group

    • 支持的OSCCLK(Hz)为:86M、12M、6M、3M、1.5M、1M、32K、8K

    • 频率的工作范围是(OSCCLK/2)到(OSCCLK/2^34) ,例如OSCCLK = 12MHz,则范围是(0.0007Hz~6MHz);

    • 支持double buffer来防止产生错误波形,即波形更新会等待当前波形完全生成之后;

    • 支持sync功能,即Group内的PWM在同一个时刻产生波形,一般一组Group中会包含4个channel的PWM

    • 支持round功能,即同Group内的PWM会在产生特定数量的脉冲后停止

    • 支持hold功能,即同Group内的PWM会在完成当前周期的波形后暂停,常用于改变波形的设定,可设定暂停时间内的高低电平

    • 支持stop功能,即同Group内的PWM会紧急停止


    3. 相关概念说明

    3.1. 频率和占空比

    • 频率(frequency)

      每秒钟信号从高电平到低电平再回到高电平的次数。

    • 占空比(duty cycle)

      高电平持续时间和低电平持续时间之间的比例。

    • 举例说明

      假设PWM的OSCCLK频率为12M,那么可设置的频率范围为:0.0007Hz~6MHz;

      设定PWM0和PWM1为频率120Hz,占空比25%的波形,且PWM1相对于PWM0有180°的相位偏移,那么各参数配置如下:

      period duty shift
      PWM0 120Hz 25% 0%
      PWM1 120Hz 75% 50%

      产生的波形如下图:

    3.2. 普通精度模式

    rtos config中不开启CONFIG_SSTAR_PWM_EXTEND(Support high precision calculation),则使用普通精度模式,该模式下配置PWM的period的单位为Hz,duty cycle的单位为百分比。

    假设要设置PWM0频率为10000HZ,占空比为50%,则:

    period = 10000

    duty cycle = 50

    3.3. 高精度模式

    rtos config中开启CONFIG_SSTAR_PWM_EXTEND(Support high precision calculation)选项时,则使用高精度模式,该模式下配置PWM的period和duty_cycle均使用纳秒为单位,所以要先计算周期和占空比的值。

    假设要设置PWM0频率为10000.5HZ,占空比为49.5%,则:

    period = 10^9 ÷ 10000.5 = 99995

    duty cycle = 99995 * 49.5% = 49498

    由此可见,高精度模式的优势在于参数设定支持到小数。

    3.4. GROUP相关概念

    3.4.1. Sync mode

    sync mode可以将每个pwm channel加入到各自的Group群组中,完成同时对多个PWM进行控制的目的,一个Group有3~4个pwm channel,且Group与channlel对应关系如下:

    Group Group Member
    Group0 PWM0、PWM1、PWM2、PWM3
    Group1 PWM4、PWM5、PWM6、PWM7
    Group2 PWM8、PWM9、PWM10

    3.4.2. Hold mode

    Group的Hold功能会在pwm完成当前周期的波形后停止,并触发中断,此时可以改变各channel波形的配置以保持同步,完成修改后会关闭hold 功能,pwm就会重新产生新的波形,每组group都有自己独立的hold功能。

    3.4.3. Round mode

    round功能会在同group内的所有channel完成一定数量的脉冲后停止,每组group都有自己独立的round功能。

    3.4.4. Stop mode

    stop功能可以让当前group中的PWM立即停止(不会等当前周期完成)并维持结束时的电平,每组group都有自己独立的stop功能。

    注意:stop 时间不建议太长,尤其是pwm停止后维持的电平为高电平时。


    4. RTOS用法介绍

    4.1 DRIVER PATH

    sc/driver/sysdriver/pwm/drv/pub/drv_pwm.h
    sc/driver/sysdriver/pwm/drv/src/drv_pwm.c
    sc/driver/sysdriver/pwm/drv/src/drv_pwm_test.c
    sc/driver/sysdriver/pwm/hal/chipname/src/hal_pwm.c
    sc/driver/sysdriver/pwm/hal/chipname/inc/hal_pwm.h
    sc/driver/sysdriver/pwm/hal/chipname/inc/hal_pwm_cfg.h
    

    4.2 CONFIG配置

    #make menuconfig
    
    BSP Driver Options --->
        [*] Support PWM driver
        [*] Support high precision calculation
    

    4.3 SYSDESC配置

    chipname.sysi文件位于sc/driver/sysdriver/sysdesc/hal/chipname/pub, 下文以pwm0做举例,完整请见chipname.sysi

    <pwm0>
        [reg_u32_u16] 0x1F003400 0x37;
        [group_u32] 0;
        [interrupts_u32] INT_IRQ_PWM_INT_ALL;
        [camclk_u16] CAMCLK_pm_pwm;
        [clk_level_u8] 0;
        [status_u8] 1;
    

    pwm驱动中支持配置的属性如下表:

    属性 描述 设定值 备注
    reg_u32_u16 指定bank的地址 不需要修改
    camclk_u16 指定时钟源 不需要更改
    interrupts_u32 指定硬件中断号 不需要更改
    clk_level_u8 选择时钟挡位 pwm010可选07分别对应12M/32K/1.5M/1M/8K/86M/6M/3M 每个channel选择必须一致
    group_u32 选择是否加入group 不配置该属性则不加入group,加入group配置0/½/3,详见Group与channlel对应关系 可根据需要修改
    status_u8 选择是否使能驱动 1表示enable;0表示disable 可根据需要修改

    4.4 PADMUX设定

    sc/driver/sysdriver/sysdesc/hal/chipname/pub/chipname-xxx.sys文件中的padmux节点配置引脚复用功能

    <padmux>
        [schematic_u32_u32_u32]
        PAD_PWM0     PINMUX_FOR_PWM0_MODE_1    MDRV_PUSE_PWM0,
        PAD_PWM1     PINMUX_FOR_PWM1_MODE_1    MDRV_PUSE_PWM1,
        PAD_GPIO2    PINMUX_FOR_PWM2_MODE_4    MDRV_PUSE_PWM2,
        PAD_GPIO3    PINMUX_FOR_PWM3_MODE_4    MDRV_PUSE_PWM3,
        PAD_GPIO4    PINMUX_FOR_PWM4_MODE_3    MDRV_PUSE_PWM4,
        PAD_GPIO5    PINMUX_FOR_PWM5_MODE_3    MDRV_PUSE_PWM5,
        PAD_GPIO6    PINMUX_FOR_PWM6_MODE_3    MDRV_PUSE_PWM6,
        PAD_GPIO7    PINMUX_FOR_PWM7_MODE_3    MDRV_PUSE_PWM7,
        PAD_GPIO0    PINMUX_FOR_PWM8_MODE_1    MDRV_PUSE_PWM8,
        PAD_GPIO14   PINMUX_FOR_PWM9_MODE_3    MDRV_PUSE_PWM9,
        PAD_GPIO15   PINMUX_FOR_PWM10_MODE_3   MDRV_PUSE_PWM10>;
        [status_u8] 1;
    

    4.5 API说明

    头文件位于sc/driver/sysdriver/pwm/drv/pub/drv_pwm.h

    struct pwm_ch_cfg
    {
        u64 duty;     //设定占空比,实际占空比=duty-shift
        u64 shift;    //设定起始相位
        u64 period;   //设定周期
        u32 polarity; //极性设置:0-正常,1-极性取反
        u32 channel;  //指定channel
    };
    
    struct pwm_gp_cfg
    {
        u64 duty;
        u64 shift;
        u8  polar;
        u32 group;
        u64 period;
    };
    
    extern int drv_pwm_set_period(u32 channel, u64 period, u8 sync);
    extern int drv_pwm_set_duty(u32 channel, u64 duty, u8 sync);
    extern int drv_pwm_set_shift(u32 channel, u64 shift, u8 sync);
    extern int drv_pwm_set_polarity(u32 channel, u64 polar, u8 sync);
    extern int drv_pwm_set_chan_config(struct pwm_ch_cfg * pwm_ch);
    extern int drv_pwm_get_chan_config(struct pwm_ch_cfg * pwm_ch);
    extern int drv_pwm_channel_enable(u32 channel, u8 enable);
    extern int drv_pwm_set_group_config(struct pwm_gp_cfg *pwm_gp);
    extern int drv_pwm_get_group_config(struct pwm_gp_cfg *pwm_gp);
    extern int drv_pwm_group_enable(u32 group, u8 enable);
    extern int drv_pwm_stop_enable(u32 group, u8 stop_en);
    extern int drv_pwm_update_enable(u32 grou);
    extern int drv_pwm_round_enable(u32 group, u32 round_num);
    

    4.5.1. drv_pwm_set_period

    • 目的

      设置pwm周期

    • 语法

      int drv_pwm_set_period(u32 channel, u64 period, u8 sync)
      
    • 参数

      参数名称 描述
      channel 选择pwm的通道
      period pwm周期,高精度模式以ns为单位,低精度模式以Hz为单位
      sync 0表示配置在此次接口调用后生效,1表示此次接口调用后不生效,生效需要调用drv_pwm_update_enable接口
    • 返回值

      结果 描述
      成功 返回0
      失败 返回负数

    4.5.2. drv_pwm_set_duty

    • 目的

      设置pwm占空比

    • 语法

      drv_pwm_set_duty(u32 channel, u64 duty, u8 sync)
      
    • 参数

      参数名称 描述
      channel 选择pwm的通道
      duty pwm占空比,高精度模式以ns为单位,低精度模式以Hz为单位
      sync 0表示配置在此次接口调用后生效,1表示此次接口调用后不生效,生效需要调用drv_pwm_update_enable接口
    • 返回值

      结果 描述
      成功 返回0
      失败 返回负数

    4.5.3. drv_pwm_set_shift

    • 目的

      设置pwm相位偏移

    • 语法

      int drv_pwm_set_shift(u32 channel, u64 shift, u8 sync)
      
    • 参数

      参数名称 描述
      channel 选择pwm的通道
      shift pwm相位偏移,高精度模式以ns为单位,低精度模式以Hz为单位
      sync 0表示配置在此次接口调用后生效,1表示此次接口调用后不生效,生效需要调用drv_pwm_update_enable接口
    • 返回值

      结果 描述
      成功 返回0
      失败 返回负数

    4.5.4. drv_pwm_set_polarity

    • 目的

      设置pwm极性

    • 语法

      int drv_pwm_set_polarity(u32 channel, u64 polar, u8 sync)
      
    • 参数

      参数名称 描述
      channel 选择pwm的通道
      polar pwm极性,0:normal,1:invert
      sync 0表示配置在此次接口调用后生效,1表示此次接口调用后不生效,生效需要调用drv_pwm_update_enable接口
    • 返回值

      结果 描述
      成功 返回0
      失败 返回负数

    4.5.5. drv_pwm_set_chan_config

    • 目的

      配置pwm指定通道的属性

    • 语法

      int drv_pwm_set_chan_config(struct pwm_ch_cfg * pwm_ch)
      
    • 参数

      参数名称 描述
      pwm_ch 用于配置pwm的通道、周期、占空比、相位偏移和极性信息
    • 返回值

      结果 描述
      成功 返回0
      失败 返回负数

    4.5.6. drv_pwm_get_chan_config

    • 目的

      获取当前pwm通道的属性

    • 语法

      int drv_pwm_get_chan_config(struct pwm_ch_cfg * pwm_ch)
      
    • 参数

      参数名称 描述
      pwm_ch 用于获取pwm的通道、周期、占空比、相位偏移和极性信息
    • 返回值

      结果 描述
      成功 返回0
      失败 返回负数

    4.5.7. drv_pwm_channel_enable

    • 目的

      使能pwm配置

    • 语法

      int drv_pwm_channel_enable(u32 channel, u8 enable)
      
    • 参数

      参数名称 描述
      channel 选择pwm的通道
      enable 1:enable,0:disable
    • 返回值

      结果 描述
      成功 返回0
      失败 返回负数

    4.5.8. drv_pwm_set_group_config

    • 目的

      配置group属性

    • 语法

      int drv_pwm_set_group_config(struct pwm_gp_cfg *pwm_gp)
      
    • 参数

      参数名称 描述
      pwm_gp 用于配置pwm group的通道、周期、占空比、相位偏移和极性信息,生效需要调用drv_pwm_update_enable接口
    • 返回值

      结果 描述
      成功 返回0
      失败 返回负数

    4.5.9. drv_pwm_get_group_config

    • 目的

      获取当前group的属性配置

    • 语法

      int drv_pwm_get_group_config(struct pwm_gp_cfg *pwm_gp)
      
    • 参数

      参数名称 描述
      pwm_gp 用于获取pwm group的通道、周期、占空比、相位偏移和极性信息
    • 返回值

      结果 描述
      成功 返回0
      失败 返回负数

    4.5.10. drv_pwm_group_enable

    • 目的

      使能pwm group功能

    • 语法

      int drv_pwm_group_enable(u32 group, u8 enable)
      
    • 参数

      参数名称 描述
      group 选择要使能pwm波形的group
      enable 1:enable,0:disable
    • 返回值

      结果 描述
      成功 返回0
      失败 返回负数

    4.5.11. drv_pwm_stop_enable

    • 目的

      使能stop功能

    • 语法

      int drv_pwm_stop_enable(u32 group, u8 stop_en)
      
    • 参数

      参数名称 描述
      group 选择要使能停止功能的group
      stop_en 1:enable,波形停止;0:disable,波形恢复
    • 返回值

      结果 描述
      成功 返回0
      失败 返回负数

    4.5.12. drv_pwm_round_enable

    • 目的

      设置round mode的脉冲数量

    • 语法

      int drv_pwm_round_enable(u32 group, u32 round_num)
      
    • 参数

      参数名称 描述
      group 选择使能round mode的group
      round_num 指定输出PWM波形的周期数
    • 返回值

      结果 描述
      成功 返回0
      失败 返回负数

    4.5.13. drv_pwm_update_enable

    • 目的

      更新pwm配置

    • 语法

      int drv_pwm_update_enable(u32 group)
      
    • 参数

      参数名称 描述
      group 选择要进行参数更新的group
    • 返回值

      结果 描述
      成功 返回0
      失败 返回负数

    4.6 DEMO

    demo源码位于sc/driver/sysdriver/pwm/drv/src/drv_pwm_test.c


    5. DEBUG方法

    5.1 PWM各接口不存在

    • 检查SYS PWM节点的status是否为1

    • 检查kernel config是否配置,详见4.3. SYSDESC配置

    5.2 配置后PWM无波形产生

    Step1: 首先确认测量的引脚是否正确:打开对应的原理图确认即可,如果没有错误的话,则进行下一步。

    Step2: 确认对应的PWM mode是否生效,引脚复用失败主要有两个原因:

    原因一:该引脚没有设置为PWM mode,设置方法详见4.4 PADMUX配置

    原因二:有优先级比PWM mode更高级别的padmux mode被开启

    Step3:检查pwm相关参数是否设置成功