树莓派硬件PWM的使用方法

最近折腾一个调光显示屏,厂商把调光的编程接口暴露成了PWM,所以就折腾了一下树莓派的PWM输出能力。这里面有一些散落在不同文档中的内容,还有一些不知道从什么文档里查到的东西,归纳在这里,以备后来者之需。

树莓派的40 pin通用引脚可以输出PWM信号,用于表示一个连续量以操作电机控制器、调光灯等设备。他的PWM输出有两种:软件PWM其实就是普通的GPIO输出,在一个线程里定时开关,优点是所有的GPIO引脚都可以做,缺点是工作频率、精度都比较低(在新的pigpio库里使用高精度时钟改善了软件PWM的精度,以前老的python库实现超过几百Hz就完全不准了)。而硬件PWM是使用树莓派CPU内置的PWM硬件,将它的信号导出到40 pin引脚,优点是精度和工作频率都很高,缺点是可用数量少,只有两路。

硬件PWM的配置

想要使用硬件PWM,首先显然是确认有哪些引脚可以输出硬件PWM。参考/boot/overlays/README的内容,只有GPIO18是在全部树莓派平台上都能作为硬件PWM输出脚的。其它引脚是否可用于此,可以使用raspi-gpio程序,例如在我的树莓派3B上面:

$ raspi-gpio funcs 12
GPIO, DEFAULT PULL, ALT0, ALT1, ALT2, ALT3, ALT4, ALT5
12, DOWN, PWM0, SD4, DPI_D8, AVEOUT_VID8, AVEIN_VID8, ARM_TMS
$ raspi-gpio funcs 41
GPIO, DEFAULT PULL, ALT0, ALT1, ALT2, ALT3, ALT4, ALT5
41, DOWN, PWM1, SD5, TE0, SD1_DAT5, SPI2_MOSI, RXD1

可以看到GPIO12的第零号替代功能是PWM0,而GPIO41的第零号替代功能是PWM1。

然后需要在树莓派的启动配置文件/boot/config.txt里面加载对应的设备树overlay,并设置参数,比如:

dtoverlay=pwm,pin=12,func=4

就会将PWM开启在12号GPIO上。注意此处的func号必须与引脚的alt功能序号匹配,有个很奇怪的顺序:

Func 0 = Input
Func 1 = Output
Func 2 = Alt 5
Func 3 = Alt 4
Func 4 = Alt 0
Func 5 = Alt 1
Func 6 = Alt 2
Func 7 = Alt 3

所以这里func设为4,对应alt0,因为raspi-gpio告诉我们12号GPIO的PWM功能在alt0上。

硬件PWM的使用

Linux内核通过sysfs支持硬件PWM,所以这个部分的内容不仅限于树莓派,实际上所有实现了对应驱动的开发板都一样。

树莓派的raspbian系统映像已经提供了对应的驱动,可以直接使用。修改并保存/boot/config.txt之后重启设备,如果设置正确,可以在目录/sys/class/pwm中看到一些东西,比如:

$ ls /sys/class/pwm
pwmchip0
$ ls /sys/class/pwm/pwmchip0
device  export  npwm  power  pwm0  subsystem  uevent  unexport

这些伪文件就是Linux内核PWM驱动提供的操纵接口,在shell里可以通过cat读,通过echo重定向写。在任意编程语言里也可以通过读写文件的接口进行同样的操作。

首先创建一个PWM的导出,向export写几,就会创建对应的目录在pwmchipX里面:

$ echo 0 >/sys/class/pwm/pwmchip0/export
$ ls /sys/class/pwm/pwmchip0/pwm0
capture  duty_cycle  enable  period  polarity  power  uevent

这里面,period是以纳秒计数的PWM周期,duty_cycle是以纳秒计数的每周期高电平时间。比如我想要一个20KHz的PWM,占空比为80%,那我就应当:

$ cd /sys/class/pwm/pwmchip0/pwm0
$ echo 50000 >period # 两万Hz的时长是五万纳秒
$ echo 10000 >duty_cycle # 占空比80%,那么20%的时长就是一万纳秒

然后向enable写0或者1进行开关。

$ echo 1 >enable # 立即开启

关闭之后不会清空原有设置,再次打开会以之前设置的参数运行PWM。

如果需要释放资源,向/sys/clas/pwm/pwmchipX/unexport写对应的序号,会清空对应的PWM导出目录,并且删除配置。

你可能感兴趣的:(树莓派硬件PWM的使用方法)