PWM使用参考
1. 概述¶
-
概述
PWM( Pulse Width Modulation)模块通过改变占空比来改变输出的电流、电压进而控制电机转速、液晶屏调光等。
-
说明
目前PWM支持的period范围:
pwm driver的period精度支持2档调节,普通模式精度范围为44Hz – 6MHz;设置更高的精度时在menuconfig中打开
CONFIG_PWM_NEW
选项,此时精度范围为0.000698Hz – 6MHz。
2. 频率和占空比¶
-
频率
每秒钟信号从高电平到低电平再回到高电平的次数。
-
占空比
高电平持续时间和低电平持续时间之间的比例。
3. PWM的PADMUX与配置方法¶
PWM group0 | MODE | PAD | PWM group1 | MODE | PAD | PWM group2 | MODE | PAD |
---|---|---|---|---|---|---|---|---|
0 | 1 | PAD_GPIO8 | 4 | 1 | PAD_GPIO12 | 8 | 1 | PAD_OM_GPIO10 |
2 | PAD_GPIO0 | 2 | PAD_GPIO4 | 2 | PAD_SD0_GPIO0 | |||
3 | PAD_PM_GPIO0 | 3 | PAD_PM_UART_RX1 | 3 | PAD_ETH_LED1 | |||
4 | PAD_SR1_IO00 | 4 | PAD_PM_GPIO4 | 4 | PAD_SR1_IO00 | |||
5 | PAD_I2C0_SCL | 5 | PAD_I2S0_BCK | 5 | PAD_GPIO12 | |||
6 | PAD_FUART_RX | 6 | PAD_PM_SPI_CZ | 6 | PAD_I2C0_SCL | |||
1 | 1 | PAD_GPIO9 | 5 | 1 | PAD_GPIO13 | 7 | PAD_SR0_I013 | |
2 | PAD_GPIO1 | 2 | PAD_GPIO5 | 8 | PAD_PM_GPIO0 | |||
3 | PAD_PM_GPIO1 | 3 | PAD_PM_UART_TX1 | 9 | 1 | PAD_PM_GPIO9 | ||
4 | PAD_SR1_I000 | 4 | PAD_PM_GPIO5 | 2 | PAD_FUART_CTS | |||
5 | PAD_I2C0_SDA | 5 | PAD_I2S0_WCK | 3 | PAD_ETH_LED0 | |||
6 | PAD_FUART_TX | 6 | PAD_PM_SPI_CK | 4 | PAD_SR1_IO12 | |||
2 | 1 | PAD_GPIO10 | 6 | 1 | PAD_GPIO14 | 5 | PAD_GPIO13 | |
2 | PAD_GPIO2 | 2 | PAD_GPIO6 | 6 | PAD_I2C0_SDA | |||
3 | PAD_PM_GPIO2 | 3 | PAD_PM_I2CM_SCL | 7 | PAD_I2S0_MCLK | |||
4 | PAD_SR1_IO02 | 4 | PAD_PM_GPIO6 | 8 | PAD_PM_GPIO1 | |||
5 | PAD_ETH_LED0 | 5 | PAD_I2S0_DI | 10 | 1 | PAD_PM_GPIO1 | ||
6 | PAD_FUART_CTS | 6 | PAD_PM_SPI_DI | 2 | PAD_PM_GPIO4 | |||
3 | 1 | PAD_GPIO11 | 7 | 1 | PAD_GPIO15 | |||
2 | PAD_GPIO3 | 2 | PAD_GPIO7 | |||||
3 | PAD_PM_GPIO3 | 3 | PAD_PM_I2CM_SDA | |||||
4 | PAD_SR1_IO03 | 4 | PAD_PM_GPIO7 | |||||
5 | PAD_ETH_LED1 | 5 | PAD_I2S0_DO | |||||
6 | PAD_FUART_RTS | 6 | PAD_PM_SPI_DO |
4. DTSI节点属性说明¶
4.1. DTSI中PWM节点¶
PWM在dtsi中的节点如下图所示:
4.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,Pudding默认全PAD_UNKNOWN即可
-
Status
节点状态
5. 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这个config可以提高PWM设置的精度和范围,可以根据情况选择打开与否。(不打开时PWM可以设置的范围为44Hz– 6MHz,打开时可以设置的范围为0.000698Hz – 6MHz)
6. PADMUX配置¶
在padmux.dtsi中配置mode格式如下图的,"\<>"中第一个值为PAD值,第二个值为要设置的mode,第三个值为PAD在该mode下对应的功能;
如图中1配置完成后,请检查图中2和3,是否有其他的PAD也设置成了需要设置的mode,重复设置会引起冲突导致配置padmux失效,如果冲突的mode不需要使用则可以将其注释掉,如果需要使用,请重新选择mode。
7. 配置PWM输出(普通模式)¶
7.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
7.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
8. GROUP相关概念¶
8.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都相同,这样波形的周期就是同时开始同时结束,可以用来实现电机同步等功能。
8.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
8.3. Hold功能¶
Group的Hold功能可以让加入到Group中的PWM在完成Hold命令前的周期波形之后停止。
Hold命令如下:
echo GROUP_ID > group_hold
Group的Hold功能分为2种:
-
Hold_mode_0
-
Hold_mode_1
两者的区别为: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模式)。
图 8‑1:HOLD_MODE_0
图 8‑2:HOLD_MODE_1
8.4. Round功能¶
Round功能可以让Group中的PWM出完指定的周期数之后停止并触发Round中断。
Round命令如下:
echo GROUP_ID round > group_round
8.5. Stop功能¶
Stop功能可以让当前Group中的PWM立即停止(不会等当前周期完成),PWM会维持结束时的电平。
Stop命令如下:
echo GROUP_ID enable > group_stop
9. 配置PWM输出(GROUP模式)¶
Group模式为了保持PWM之间的同步会将用户的配置先暂存,只有在Enable以及Hold中断触发时将用户的配置写到寄存器中才生效。
使用中需要Group在enable之后,更改PWM的period、begin、end的值时,先进行配置,再下Hold_mode_0使能命令来触发中断,将新的配置下到寄存器中来使其生效。
9.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个周期的
9.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个周期的