PWM使用参考


REVISION HISTORY

Revision No.
Description
Date
1.0
  • Initial release
  • 01/29/2024

    1. 概述

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


    2. 功能描述

    • 支持PWM的channel数量为12个,其中channel 0~7支持加入各自的Group,channel 8~11不支持Group功能

    • channel 0~7支持的OSCCLK(Hz)为:86M、12M、6M、3M、1.5M、750K,channel 8~11支持的OSCCLK(Hz)为:12M;

    • 频率的工作范围是(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中不开启Support high precision calculation,则使用普通精度模式,该模式下配置PWM的period的单位为Hz,duty cycle的单位为百分比。

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

    period = 10000

    duty cycle = 50

    3.3. 高精度模式

    rtos config中开启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有4个pwm channel,且Group与channlel对应关系如下:

    Group Group Member
    Group0 PWM0、PWM1、PWM2、PWM3
    Group1 PWM4、PWM5、PWM6、PWM7

    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.sys文件位于sc/driver/sysdriver/sysdesc/hal/chipname/pub, 下文以pwm0做举例,完整请见chipname.sys

    <pwm0>
        [reg_u32_u16] 0x1F203200 0x37;
        [group_u32] 0;
        [camclk_u16] CAMCLK_pwm;
        [clk_level_u8] 0;
        [interrupts_u32] INT_IRQ_PWM;
        [status_u8] 1;
    

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

    属性 描述 设定值 备注
    reg_u32_u16 指定bank的地址 不需要修改
    group_u32 选择是否加入group 1表示加入,0表示不加入 可根据需要修改
    camclk_u16 指定时钟源 不需要更改
    clk_level_u8 选择时钟挡位 channel07:05分别对应12M/6M/3M/1.5M/750K/86M,channel8~11只有12M档,配置0 每个channel选择必须一致
    interrupts_u32 指定硬件中断号 不需要更改
    status_u8 选择是否使能驱动 1表示enable;0表示disable 可根据需要修改

    4.4 PADMUX设定

    方法一

    通过使能PADMUX驱动,在chipname-padmux.c文件配置引脚复用功能,该文件位于sc/driver/sysdriver/padmux/hal/chipname/src,只需要在对应的schematic属性添加如下内容中设定:

    pad_info_t schematic[] =
    {
        {PAD_GPIO0,       PINMUX_FOR_PWM0_MODE_1,          MDRV_PUSE_PWM0},
        {PAD_GPIO1,       PINMUX_FOR_PWM1_MODE_1,          MDRV_PUSE_PWM1},
        {PAD_GPIO2,       PINMUX_FOR_PWM2_MODE_3,          MDRV_PUSE_PWM2},
        {PAD_GPIO3,       PINMUX_FOR_PWM3_MODE_1,          MDRV_PUSE_PWM3},
        {PAD_GPIO4,       PINMUX_FOR_PWM4_MODE_1,          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_PM_PWM0,     PINMUX_FOR_PM_PWM0_MODE_1,       MDRV_PUSE_PWM8},
        {PAD_PM_PWM1,     PINMUX_FOR_PM_PWM1_MODE_1,       MDRV_PUSE_PWM9},
        {PAD_PM_PWM2,     PINMUX_FOR_PM_PWM2_MODE_1,       MDRV_PUSE_PWM10},
        {PAD_PM_PWM3,     PINMUX_FOR_PM_PWM3_MODE_1,       MDRV_PUSE_PWM11},
    };
    

    第一列为引脚索引号,可以在sc/drivers/sysdriver/gpio/hal/chipname/pub/gpio.h中查询;

    第二列为模式定义,可以在sc/drivers/sysdriver/gpio/hal/chipname/pub/padmux.h中查询;

    第三列为引脚及搭配模式的索引名称,可以在sc/drivers/sysdriver/padmux/drv/pub/drv_puse.h中查询;

    方法二

    sc/driver/sysdriver/sysdesc/hal/chipname/pub中的padmux节点配置引脚复用功能

    <padmux>
        [schematic_u32_u32_u32]
        PAD_GPIO0 PINMUX_FOR_PWM0_MODE_1 MDRV_PUSE_PWM0,
        PAD_GPIO1 PINMUX_FOR_PWM1_MODE_1 MDRV_PUSE_PWM1,
        PAD_GPIO2 PINMUX_FOR_PWM2_MODE_3 MDRV_PUSE_PWM2,
        PAD_GPIO3 PINMUX_FOR_PWM3_MODE_1 MDRV_PUSE_PWM3,
        PAD_GPIO4 PINMUX_FOR_PWM4_MODE_1 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_PM_PWM0 PINMUX_FOR_PM_PWM0_MODE_1 MDRV_PUSE_PWM8,
        PAD_PM_PWM1 PINMUX_FOR_PM_PWM1_MODE_1 MDRV_PUSE_PWM9,
        PAD_PM_PWM2 PINMUX_FOR_PM_PWM2_MODE_1 MDRV_PUSE_PWM10,
        PAD_PM_PWM3 PINMUX_FOR_PM_PWM3_MODE_1 MDRV_PUSE_PWM11;
        [status_u8] 1;
    

    各PWM硬件组padmux罗列

    PWM CHANNEL register addr padmod PAD PIN_NAME
    PWM0 bank 103cH offset 65H bit[2:0] 1 PAD_GPIO0 GPIO0
    2 PAD_FUART_TX FUART_TX
    3 PAD_I2C0_SCL I2C0_SCL
    4 PAD_SR_RST1 SR_RST1
    5 PAD_PM_FUART_RX PM_FUART_RX
    6 PAD_I2C0_SCL SD0_CDZ
    PWM1 bank 103cH offset 65H bit[6:4] 1 PAD_GPIO1 GPIO1
    2 PAD_SR_MCLK1 SR_MCLK1
    3 PAD_FUART_RX FUART_RX
    4 PAD_I2C0_SDA I2C0_SDA
    5 PAD_PM_FUART_TX PM_FUART_TX
    6 PAD_GPIO10 GPIO10
    7 PAD_SD0_D1 SD0_D1
    PWM2 bank 103cH offset 65H bit[10:8] 1 PAD_OUTP_RX0_CH3 OUTP_RX0_CH3
    2 PAD_FUART_CTS FUART_CTS
    3 PAD_GPIO2 GPIO2
    4 PAD_PM_FUART_CTS PM_FUART_CTS
    5 PAD_SD0_D0 SD0_D0
    PWM3 bank 103cH offset 65H bit[14:12] 1 PAD_GPIO3 GPIO3
    2 PAD_FUART_RTS FUART_RTS
    3 PAD_SD0_CLK SD0_CLK
    4 PAD_PM_FUART_RTS PM_FUART_RTS
    5 PAD_OUTN_RX0_CH3 OUTN_RX0_CH3
    PWM4 bank 103cH offset 66H bit[2:0] 1 PAD_GPIO4 GPIO4
    2 PAD_MSPI_CK MSPI_CK
    3 PAD_SD0_CMD SD0_CMD
    4 PAD_OUTP_RX0_CH4 OUTP_RX0_CH4
    PWM5 bank 103cH offset 66H bit[6:4] 1 PAD_OUTN_RX0_CH4 OUTN_RX0_CH4
    2 PAD_MSPI_DI MSPI_DI
    3 PAD_GPIO5 GPIO5
    4 PAD_SD0_D3 SD0_D3
    PWM6 bank 103cH offset 66H bit[10:8] 1 PAD_SD0_D2 SD0_D2
    2 PAD_MSPI_DO MSPI_DO
    3 PAD_GPIO6 GPIO6
    4 PAD_OUTP_RX0_CH5 OUTP_RX0_CH5
    5 PAD_PM_GPIO11 PM_GPIO11
    PWM7 bank 103cH offset 66H bit[14:12] 1 PAD_PM_GPIO12 PM_GPIO12
    2 PAD_MSPI_CZ MSPI_CZ
    3 PAD_GPIO7 GPIO7
    4 PAD_OUTN_RX0_CH5 OUTN_RX0_CH5
    5 PAD_GPIO8 GPIO8
    PWM8 bank 3fH offset 51H bit[2:0] 1 PAD_PM_PWM0 PM_PWM0
    2 PAD_PM_GPIO0 PM_GPIO0
    4 PAD_PM_PSPI0_DI PM_PSPI0_DI
    5 PAD_PM_GPIO12 PM_GPIO12
    PWM9 bank 3fH offset 51H bit[6:4] 1 PAD_PM_PWM1 PM_PWM1
    2 PAD_PM_GPIO1 PM_GPIO1
    3 PAD_PM_PSPI0_DO PM_PSPI0_DO
    4 PAD_PM_GPIO11 PM_GPIO11
    PWM10 bank 3fH offset 51H bit[10:8] 1 PAD_PM_PWM2 PM_PWM2
    2 PAD_PM_PSPI0_CZ PM_PSPI0_CZ
    3 PAD_PM_GPIO9 PM_GPIO9
    4 PAD_PM_I2C_CLK PM_I2C_CLK
    PWM11 bank 3fH offset 51H bit[14:12] 1 PAD_PM_PWM3 PM_PWM2
    2 PAD_PM_I2C_SDA PM_I2C_SDA
    3 PAD_PM_GPIO10 PM_GPIO10
    4 PAD_PM_PSPI0_CK PM_PSPI0_CK

    4.5 API说明

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

    4.5.1. drv_pwm_set_period

    • 目的

      设置pwm周期。

    • 语法

      int drv_pwm_set_period(struct pwm_ch_cfg *pwm_ch, u8 sync);
      
    • 参数

      参数名称 描述
      pwm_ch 用于配置pwm的通道和周期信息
      sync 1表示配置在此次接口调用后生效,0表示此次接口调用后不生效,生效需要调用drv_pwm_update_enable接口
    • 返回值

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

    4.5.2. drv_pwm_set_duty

    • 目的

      设置pwm占空比。

    • 语法

      int drv_pwm_set_duty(struct pwm_ch_cfg *pwm_ch, u8 sync);
      
    • 参数

      参数名称 描述
      pwm_ch 用于配置pwm的通道和占空比信息
      sync 1表示配置在此次接口调用后生效,0表示此次接口调用后不生效,生效需要调用drv_pwm_update_enable接口
    • 返回值

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

    4.5.3. drv_pwm_set_shift

    • 目的

      设置pwm相位偏移。

    • 语法

      int drv_pwm_set_shift(struct pwm_ch_cfg *pwm_ch, u8 sync);
      
    • 参数

      参数名称 描述
      pwm_ch 用于配置pwm的通道和相位偏移信息
      sync 1表示配置在此次接口调用后生效,0表示此次接口调用后不生效,生效需要调用drv_pwm_update_enable接口
    • 返回值

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

    4.5.4. drv_pwm_set_polarity

    • 目的

      设置pwm极性。

    • 语法

      int drv_pwm_set_polarity(struct pwm_ch_cfg *pwm_ch, u8 sync);
      
    • 参数

      参数名称 描述
      pwm_ch 用于配置pwm的通道和极性信息
      sync 1表示配置在此次接口调用后生效,0表示此次接口调用后不生效,生效需要调用drv_pwm_update_enable接口
    • 返回值

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

    4.5.5. drv_pwm_channel_config

    • 目的

      设置pwm配置。

    • 语法

      int drv_pwm_channel_config(struct pwm_ch_cfg *pwm_ch);
      
    • 参数

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

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

    4.5.6. drv_pwm_channel_enable

    • 目的

      使能pwm配置。

    • 语法

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

      参数名称 描述
      channel 用于配置pwm的通道信息
      enable 1表示使能,0表示失能
    • 返回值

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

    4.5.7. drv_pwm_group_config

    • 目的

      设置pwm group配置。

    • 语法

      int drv_pwm_group_config(struct pwm_gp_cfg *pwm_gp);
      
    • 参数

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

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

    4.5.8. drv_pwm_group_enable

    • 目的

      使能pwm group功能。

    • 语法

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

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

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

    4.5.9. drv_pwm_stop_enable

    • 目的

      使能pwm stop功能。

    • 语法

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

      参数名称 描述
      group 选择要使能停止功能的group
      stop_en 1表示使能停止功能,0表示失能
    • 返回值

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

    4.5.10. drv_pwm_round_enable

    • 目的

      设置pwm round个数。

    • 语法

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

      参数名称 描述
      group 选择要输出特定PWM波形个数的group
      round_num 表示要输出的特定PWM波形个数
    • 返回值

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

    4.5.10. drv_pwm_update_enable

    • 目的

      更新pwm配置。

    • 语法

      int drv_pwm_update_enable(u32 group);
      
    • 参数

      参数名称 描述
      group 选择要进行配置同步的pwm 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相关参数是否设置成功