最近折腾一个调光显示屏,厂商把调光的编程接口裸露成了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 12GPIO, DEFAULT PULL, ALT0, ALT1, ALT2, ALT3, ALT4, ALT512, DOWN, PWM0, SD4, DPI_D8, AVEOUT_VID8, AVEIN_VID8, ARM_TMS$ raspi-gpio funcs 41GPIO, DEFAULT PULL, ALT0, ALT1, ALT2, ALT3, ALT4, ALT541, 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 = InputFunc 1 = OutputFunc 2 = Alt 5Func 3 = Alt 4Func 4 = Alt 0Func 5 = Alt 1Func 6 = Alt 2Func 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/pwmpwmchip0$ ls /sys/class/pwm/pwmchip0device 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/pwm0capture 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导出目录,并且删除配置。