PWM使用参考
1. 概述¶
本文描述透过提供的硬件PWM如何产生特定的波型。
2. Default PWM Pad¶
PWM 00 -> PAD_GPIO8
PWM 01 -> PAD_GPIO9
PWM 02 -> PAD_GPIO10
PWM 03 -> PAD_GPIO11
PWM 04 -> PAD_GPIO12
PWM 05 -> PAD_GPIO13
PWM 06 -> PAD_GPIO14
PWM 07 -> PAD_GPIO15
PWM 08 -> PAD_SD0_GPIO0
PWM 09 -> PAD_FUART_CTS
3. LINUX PWM控制¶
3.1. Console下控制PWM¶
-
Motor hierarchy
-
Group 0
PWM 0
PWM 1
PWM 2
PWM 3
-
Group 1
PWM 4
PWM 5
PWM 6
PWM 7
-
Group 2
PWM 8
PWM 9
PWM 10
-
-
cd 马达控制路径
cd /sys/devices/virtual/mstar/motor
-
Set mode/period(frequency) / Begin/End / round number/enable/hold/stop
-
mode
echo PWM_ID enable > group_mode
ex :
echo 0 1 > group_mode # 设定PWM0为马达模式 echo 0 0 > group_mode # 取消PWM0为马达模式
-
period
echo PWM_ID period > group_period
In our driver implementation, xxxx indicates output frequency.
ex:
echo 0 2000 > group_period # PWM0 will generate 2kHz waveform
-
begin
echo PWM_ID begin > group_begin
ex:
echo 0 10 > group_begin # PWM0 will generate duty_cycle starting from 10% of the period
-
end
echo PWM_ID end > group_end
ex:
echo 0 25 > group_end # PWM0 will generate duty_cycle ending at 25% of the period
-
round
echo GROUP_ID round > group_round
ex:
echo 0 10000 > group_round # Group 0 will generate 10000 period of waveform.
-
enable
echo GROUP_ID enable > group_enable
ex:
echo 0 1 > group_enable # Group 0 start generating the waveform echo 0 0 > group_enable # Group 0 stop generating the waveform
-
hold
echo GROUP_ID > group_hold
ex:
echo 0 > group_hold # Group 0 hold the last complete waveform
-
stop
echo GROUP_ID > group_stop
ex:
echo 0 > group_stop # Group 0 immediately stop the waveform
-
duty_qe0
echo QE0_EN > group_duty_qe0
ex:
echo 0 > group_duty_qe0 # QE0 enable/disable
-
hold_mode1
echo MODE1_EN > group_hold_mode1
ex:
echo 1 > group_hold_mode1 # Mode1 enable
-
Mode 0 (keep pwm state)
在拉hold期间更改设定,且pwm值保持原始。
Mode 1 (pull low)
在拉hold期间更改设定,但pwm值数完最后一个period后会拉low。
Hold 0 会有interrupt, 这个interrupt是下了hold 0之后, 这个period结束,HW会发interrupt,然后driver在ISR里头填新的参数, 取消hold 0, 然后PWM就会产生新的参数的波型。
所以操作应如下:
红色代表是AP(用户) 的操作
蓝色代表是Driver的操作
绿色代表是HW 的行为
填参数 -> enable之后, 以下分成hold 0/1来解释
-
Hold 0
- 下新的参数 (驱动先把新的参数放在内存中)-> 打开hold 0-> 一个period结束/保持最后波型 -> ( ISR ) 驱动从内存把参数回填 PWM/放开 hold 0 -> 产生新的波型
-
Hold 1
- 打开Hold 1 -> 一个period结束/波形拉低 -> (AP确定period结束) 下新的参数 -> 放开Hold 1 -> 产生新的波形
3.2. Kernel driver控制PWM¶
#include \< linux/pwm.h>
#static struct pwm_device *mstar_pwm;
-
struct pwm_device *pwm_request(int pwm_id, const char *label)
- pwm_request - request a PWM device
-
int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
- pwm_config - change a PWM device configuration
-
int pwm_enable(struct pwm_device *pwm, int duty_ns, int period_ns)
- pwm_enable - start a PWM output toggling
sample:
- enable PWM0(PAD_PWM0)
static struct pwm_device *mstar_pwm; mstar_pwm = pwm_request(0, "MSTAR LCD"); if (IS_ERR(mstar_pwm)) { printk("Start Unable to request PWM for LCD power!\n"); return PTR_ERR(mstar_pwm); } pwm_config(mstar_pwm, 50, 1000);//duty=50, hz=1000 pwm_enable(mstar_pwm);
4. UBOOT标准 PWM控制接口¶
4.1. PWM API¶
#include \< pwm.h>
-
int pwm_init(id, div, invert)
- sets up the clock speed and whether or not it is inverted
-
int pwm_config(id, duty, period_ns)
- sets up the duty and period
-
int pwm_enable(int pwm_id)
- enables the PWM driver
-
int pwm_disable(int pwm_id)
- disables the PWM driver
参数说明:
-
Id: 0:PWM0, 1:PWM1……7:PWM7
-
DIV: 设置范围0~65535
-
Invert: 设置范围0或1
-
Duty: 设置范围0~100
-
Period: 设置范围 2~262143 (在这边的Period指的是Hz)