PWM使用参考

Version 1.1


1. 概述

PWM( Pulse Width Modulation)模块通过改变占空比来改变输出的电流、电压进而控制电机转速、液晶屏调光等。

pwm driver的period精度支持2档调节,普通模式精度范围为44Hz–6MHz;设置更高的精度时在menuconfig中打开CONFIG_PWM_NEW选项,此时精度范围为0.000698Hz– 6MHz。


2. 频率和占空比

  • 频率

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

  • 占空比

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


3. DTSI节点属性


3.1. DTSI中PWM节点

PWM在dtsi中的节点如下图所示:


3.2. 节点属性

  • compatible

    匹配使用与driver中的compatible对应

  • reg

    PWM的bank值

  • npwm

    chip有的PWM的个数

  • pm_group_base

    仅Pudding有,PM_PWM的基地址

  • clocks

    clk值

  • camclk

    clk值

  • interrupt

    PWM的中断

  • pad-ctrl

    控制PWM的padmux,仅Ispahan会使用到,Pudding默认全PAD_UNKNOWN即可

  • Status

    节点状态


4. KERNEL CONFIG

编译开启PWM,配置好要使用的config之后再命令行键入make menuconfig进入kernel配置界面:

之后依次进入Device Drivers==>SStar SoC platform drivers==>进入以下界面:

将光标移到SSTAR PWM之后按下空格即可操作:

M为将PWM driver编译为ko;

*号为将PWM driver直接编入kernel。

Support NEW PWM configuration可以提高PWM设置的精度和范围,可以根据情况选择打开与否。(不打开时PWM可以设置的范围为44Hz– 6MHz,打开时可以设置的范围为0.000698Hz – 6MHz)


5. PADMUX配置

在padmux.dtsi中配置mode格式如下图的,"<>"中第一个值为PAD值,第二个值为要设置的mode,第三个值为PAD在该mode下对应的功能;

如图中1配置完成后,请检查图中2和3,是否有其他的PAD也设置成了需要设置的mode,重复设置会引起冲突导致配置padmux失效,如果冲突的mode不需要使用则可以将其注释掉,如果需要使用,请重新选择mode。

在mercury6.dtsi的pwm节点将要设置的mode对应的pad填入pad-ctrl属性对应的位置即可。

如:pwm设置为mode1,对应pad为PAD_PWM1。


6. 配置PWM输出(普通模式)


6.1. 普通精度设置

menuconfig中不开启PWM_NEW的情况下可以配置pwm周期与占空比的精度相对较低,建议开启PWM_NEW。这种模式下配置PWM的period的单位为Hz,duty的单位为百分比。

配置方法如下:

cd sys/class/pwm/pwmchip0/      //跳转到PWM控制目录
echo 0 > export             //创建PWM0节点
cd pwm0                     //进入PWM0控制目录
echo 10000 > period             //设置周期为10000Hz
echo 50 > duty_cycle            //设置占空比为50%
echo inversed > polarity        //设置极性为反向(不设置反向为echo normal > polarity)
echo 1 > enable             //使能PWM0


6.2. 高精度设置

在menuconfig中开启PWM_NEW选项时,PWM的period与duty_sycle配置的范围更大,精度也更高。

配置方法与普通精度也不同,这种模式下配置PWM的period和duty_cycle使用纳秒为单位,所以要先计算周期和占空比的值。

要设置PWM0频率为10KHZ占空比为½,则period=10^9/10000=100000,duty_cycle=½*100000=50000。

要设置PWM1频率为30HZ占空比为½,则period=10^9/30=33333333,duty_cycle=½*33333333=16666666。

配置PWM:

cd sys/class/pwm/pwmchip0/             //跳转到PWM控制路径
echo 0 >export                         //创建PWM0节点 使用PAD_GPIO0
cd pwm0                                //进入PWM0控制路径
echo 100000 >period                    //配置周期
echo 50000 >duty_cycle                 //设置占空比
echo 1 >enable                         //使能PWM0


7. GROUP相关概念


7.1. Group功能(Sync mode)

Group功能可以同时对多个PWM进行控制(一个group至多4个),要使用PWM的Group功能需要将PWM加入到Group中(每个PWM只能加入到固定的Group中:PWM0 - 3 >Group 0 ,PWM4 – 7>Group 1,PWM8 – 10==>Group 2),可通过以下命令将一个PWM加入到Group中:

echo PWM_ID enable > group_mode

之后对加入到Group的各个PWM进行配置再Enable,这时driver会将之前的配置一起下到寄存器中再Enable Group中的PWM,Group中的PWM会同时开始出配置的波形。

Group功能的典型应用是Sync mode(也叫马达模式),这个模式要求在同一个Group中的PWM的Period都相同,这样波形的周期就是同时开始同时结束,可以用来实现电机同步等功能。


7.2. period、begin、end

period是PWM的周期,开关PWM_NEW配置period的值单位不同,详见配置PWM输出(GROUP模式),配置方法如下:

echo PWM_ID period > group_period

begin设置的是PWM 的shift值,这个值可以将PWM的相位相对于其他的PWM有一个偏移,end设置的是PWM的duty值,group中的duty与普通模式下不同,group中PWM的占空比需要将duty减去shift即end – begin。

Group中配置begin与shift的方法如下:

echo PWM_ID end > group_end
echo PWM_ID begin > group_begin

7.3. Hold功能

Group的Hold功能可以让加入到Group中的PWM在完成Hold命令前的周期波形之后停止。

Hold命令如下:

echo GROUP_ID > group_hold

Group的Hold功能分为2种:

  • Hold_mode_0

    在PWM停止以后会维持结束时电平

  • Hold_mode_1

    PWM停止之后将电平全部拉低

改变Hold的mode命令如下:

echo HOLD_mode > group_hold_mode1

在驱动中将Hold_mode_0作为Group出波形中更改PWM设置的方法,在Enable group之后配置需要更改的配置,再使用Hold_mode_0会将新配置导入到寄存器并出现新波形,这样不会影响到Group之间的PWM同步,具体操作方法见配置PWM输出(GROUP模式)。

HOLD_MODE_0:

HOLD_MODE_1:


7.4. Round功能

Round功能可以让Group中的PWM出完指定的周期数之后停止并触发Round中断。

Round命令如下:

echo GROUP_ID round > group_round

7.5. Stop功能

Stop功能可以让当前Group中的PWM立即停止(不会等当前周期完成),PWM会维持结束时的电平。

Stop命令如下:

echo GROUP_ID enable > group_stop


8. 配置PWM输出(GROUP模式)

Group模式为了保持PWM之间的同步会将用户的配置先暂存,只有在Enable以及Hold中断触发时将用户的配置写到寄存器中才生效。

使用中需要Group在enable之后,更改PWM的period、begin、end的值时,先进行配置,再下Hold_mode_0使能命令来触发中断,将新的配置下到寄存器中来使其生效。


8.1. 普通精度设置

menuconfig中不开启PWM_NEW的情况下,配置pwm周期与占空比的精度相对较低,建议开启PWM_NEW。这种模式下配置PWM的period的单位为Hz,duty的单位为千分比。配置方法如下(注意:在同一个GROUP中的PWM的period要相同):

cd sys/devices/virtual/mstar/motor/ //进入马达模式控制目录
echo 1 1 > group_mode               //将PWM1加入到GROUP模式中
echo 0 10000 > group_period         //设置PWM0的period为10000HZ
echo 0 500 > group_end              //设置PWM0的duty为500‰
echo 1 10000 > group_period         //设置PWM1的period为10000HZ
echo 1 250 > group_begin            //设置PWM1的shift为250‰
echo 1 750 > group_end              //设置PWM1的duty为750‰
echo 0 1 > group_enable             //启动Group0
echo 0 750 > group_end              //更改PWM0的duty为750‰
echo 0 1 > group_hold               //触发Group0 Hold中断使Enable之后的配置生效
echo 0 1000 > group_round           //配置Group0输出1000个周期的


8.2. 高精度设置

menuconfig中开启PWM_NEW时,PWM的period与duty_sycle配置的范围更大,精度也更高。

配置方法与普通精度也不同,这种模式下配置PWM的period和duty_cycle使用纳秒为单位,所以要先计算周期和占空比的值。

要设置PWM0频率为10KHZ占空比为½,则period=10^9/10000=100000,duty_cycle=½*100000=50000。

要设置PWM1频率为30HZ占空比为½,则period=10^9/30=33333333,duty_cycle=½*33333333=16666666。

配置PWM:

cd sys/devices/virtual/mstar/motor/     //进入马达模式控制目录
echo 1 1 > group_mode                   //将PWM1加入到GROUP模式中
echo 0 100000 > group_period                //设置PWM0的period为100000ns对应10000Hz
echo 0 50000 > group_end                //设置PWM0的duty为50000ns对应500‰
echo 1 100000 > group_period                //设置PWM1的period为100000ns对应10000HZ
echo 1 25000 > group_begin              //设置PWM1的shift为25000ns对应250‰
echo 1 75000 > group_end                //设置PWM1的duty为75000ns对应750‰
echo 0 1 > group_enable                 //启动Group0
echo 0 75000 > group_end                //更改PWM0的duty为75000ns对应750‰
echo 0 1 > group_hold                   //触发Group0 Hold中断使enable之后的设置生效
echo 0 1000 > group_round               //配置Group0输出1000个周期的