树莓派的硬件PWM模块

硬件PWM

本文针对的是Raspberry Pi 2 Model B硬件。从理论上讲,对于任意GPIO口,可以通过设定延时来输出PWM信号,这被称作软件PWM。由于Linux不是实时操作系统,对于一些要求硬实时的应用,例如通过PWM信号控制舵机,最好使用硬件PWM

树莓派的BCM2386芯片有两个PWM通道——PWM0和PWM1。PWM0可以设置在GPIO12和GPIO18上,PWM1可以设置在GPIO13上。本文使用pigpio库来实现GPIO12输出PWM信号。

使用pigpio库

首先下载并安装pigpio库。安装成功后,输入命令sudo pigpiod运行pigpio守护进程,Python接口通过和pigpio守护进程通信来控制GPIO口。函数set_PWM_dutycycleset_PWM_frequencyset_PWM_range分别控制PWM的占空比频率控制精度

set_PWM_dutycycle(user_gpio, dutycycle)函数控制PWM的占空比,user_gpio指定GPIO口,dutycycle的范围是0--rangerange默认为255,可以通过set_PWM_range函数来更改range的值,下面是一段示例代码:

1
2
3
4
5
6
7
8
9
10
11
import pigpio
import time

pi = pigpio.pi() # pi accesses the local Pi's gpios

# gpio 12 outputs pwm
pi.set_PWM_dutycycle(12, 0) # PWM off
pi.set_PWM_dutycycle(12, 64) # PWM 1/4 on
pi.set_PWM_dutycycle(12, 128) # PWM 1/2 on
pi.set_PWM_dutycycle(12, 192) # PWM 3/4 on
pi.set_PWM_dutycycle(12, 255) # PWM full on

set_PWM_frequency(user_gpio, frequency)控制PWM信号的频率,示例代码如下:

1
2
3
4
5
6
>>> pi.set_PWM_frequency(4, 0)
>>> print(pi.get_PWM_frequency(4))
10
>>> pi.set_PWM_frequency(4, 100000)
>>> print(pi.get_PWM_frequency(4))
8000

set_PWM_range(user_gpio, range_)通过设定range_值来控制PWM信号的精度。range_值越大,控制精度越高,range_值的范围是25--40000,示例代码如下:

1
2
3
pi.set_PWM_range(12, 100)   # now  25 1/4,   50 1/2,   75 3/4 on
pi.set_PWM_range(12, 500) # now 125 1/4, 250 1/2, 375 3/4 on
pi.set_PWM_range(12, 3000) # now 750 1/4, 1500 1/2, 2250 3/4 on

应用实例

这里是控制一个舵机来回转动的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import pigpio
import time

pi = pigpio.pi()
pi.set_PWM_frequency(12, 50) # frequency 50Hz
pi.set_PWM_range(12, 1000) # set range 1000
pi.set_PWM_dutycycle(12, 75) # set an initial position
time.sleep(2) # wait for 2 seconds

delay = 0.5
while True:
pi.set_PWM_dutycycle(12, 25) # 2.5%
time.sleep(delay)
pi.set_PWM_dutycycle(12, 125) # 12.5%
time.sleep(delay)

while循环中的延时是为了使舵机有充足时间转动到对应的角度。

参考

  1. Can I use the GPIO for pulse width modulation (PWM)?
  2. Raspberry Pi 2 Hardware PWM
  3. pigpio library