方波的周期,也就是一秒钟内有多少个周期,就是我们常说的频率,单位是 Hz。例如,某脉冲方波的频率为 50 Hz,即一秒钟内循环50次,那么,每个周期的时长为 1 / 50 = 0.02 秒,合 20 毫秒。
既然脉冲中一个周期内可以输出高电平或低电平,那么,高电平与低电平两者所占用的时间,就形成另一个名词——占空比。用一句话解释,就是:高电平持续的时间占整个周期的百分比。
沿用上文的举例,若周期是 20 毫秒,如果高电平持续的时间为10毫秒,那么占空比 = 10/20 = 50%;如果高电平持续的时间为 15 毫秒,那么占空比 = 15/20 = 75%,低电平占用的时间比就是 25%。但占空比的定义是关注高电平的持续时间。
咱们这一次调节发光二极管亮度的实验就是用到 PWM。当然,调节电压或电阻也能改变亮度,不过开发板自身可不能改变电压和电阻,可以用一些稳压模块来调节。
为什么脉冲可以改变灯的亮度呢?回想一下,前面咱们聊过,对开发板而言,高电平的电压是 3.3V,低电平是 0V。接到二极管正、负两脚上的电压如果相等,由于没有电势差,不产生电流,灯就熄灭;反之,存在电势差,有电流通过,灯就亮。
情形1:二极管的正极接 GPIO 口,负极接 GND (接地,始终是低电平,相对 0V 电势)。此时,如果GPIO口输出高电平,与 GND 之间存在对0V的电势差,二极管发光;反过来,如果GPIO口输出低电平,那么,0V与GND的0V位于同一参考值上,没有电势差,二极管不亮。
情形2:二极管的正极接 3.3V(供电接口始终输出高电平),负极接GPIO口。如果GPIO口输出低电平,就相当于GND的作用了,有电流通过,灯亮;如果GPIO口输出高电平,也是 3.3V,与供电口的相对电平相同,没有电势差,无电流通过,灯灭。
现在入重点了,高电平灯亮,低电平灯灭,那么高、低电平交替输出呢?也就是高 - 低 - 高 - 低 - 高 - 低……那灯就会一亮一灭,也就是在闪。但是,由于灯从亮到灭的过程会有很短的个延时,如果这延时足够短,人的眼睛就看不到灯的闪烁(不知道猫眼能不能看到),视觉延迟导致反应不过来,就没感觉了。所以,用PWM调亮度时,频率不要太低,50 - 60 Hz 明显看到闪烁;选 100-200 Hz 比较好,频率太高了效果也不好,频率高到比灯熄灭的延时还短的话,就等于灯是一直有充足的电流可用,这样它就不会暗下来了,调节亮度就没效果了。
上面说的都是基本理论,下面咱们动手干活。
先要看看在树莓派上怎么配置 PWM 功能。配置文件依然是 /boot 目录下的那个 config.txt。下面是文档说明:Name: pwm
Info: Configures a single PWM channel
Legal pin,function combinations for each channel:
PWM0: 12,4(Alt0) 18,2(Alt5) 40,4(Alt0)
52,5(Alt1)
PWM1: 13,4(Alt0) 19,2(Alt5) 41,4(Alt0) 45,4(Alt0) 53,5(Alt1)
N.B.:
1) Pin 18 is the only one available on all platforms, and
it is the one used by the I2S audio interface.
Pins 12 and 13 might be better choices on an A+, B+ or Pi2.
2) The onboard analogue audio output uses both PWM channels.
3) So be careful mixing audio and PWM.
4) Currently the clock must have been enabled and configured
by other means.
Load: dtoverlay=pwm,<param>=<val>
Params: pin
Output pin (default 18) - see table
func
Pin function (default 2 = Alt5) - see above
clock
PWM clock frequency (informational)