我用树莓派Pico学Python (4) – PWM

PWM全称是脉冲宽度调制(Pulse width modulation),也叫脉宽调制,从波形上看PWM就是方波。PWM的频率是1秒内有多少个方波脉冲,PWM的占空比是方波的一个周期内高电平所占的百分比。

介绍另一篇博文,对PWM的解释比较好:
https://blog.csdn.net/as480133937/article/details/103439546

从本专题的前几篇可以看到,树莓派Pico的GPIO可以输出高电平(可以点亮LED)或低电平(可以熄灭LED)。同时,树莓派的所有GPIO也都可以输出PWM,即按照一定的频率的高低电平的变化,而且频率和占空比可以很方便的设定和更改。

当然,按照之前闪烁LED的程序,GPIO实际上输出的也是PWM,只不过PWM的频率比较低(1Hz)。如果要提高频率、改变占空比的话,就要麻烦一些。 而按照直接输出PWM的方法,就非常的方便。

先来把闪烁LED的程序改为PWM输出的方式:

import time
from machine import Pin, PWM

# 设定GPIO25为PWM输出方式
pwm = PWM(Pin(25))
# 设定PWM的频率为10Hz,这是Pico的PWM输出的最低频率
pwm.freq(10)
# 设定PWM的占空比,取值范围0~65535, 而32768大约是一半,也就是50%
pwm.duty_u16(32768)

运行这段程序后,可以看到绿色LED10Hz的频率快速闪烁(树莓派Pico的PWM不能输出1Hz脉冲,也就不能让LED每1秒闪一次),而程序运行完毕后返回了命令提示符(如下所示),说明这段程序不是死循环,PWM是主芯片 “自动” 一直在输出的

MicroPython v1.16 on 2021-06-18; Raspberry Pi Pico with RP2040

Type "help()" for more information.
>>> %Run -c $EDITOR_CONTENT
>>> 

呼吸灯

如下程序代码来自于树莓派Pico的官方文档
https://datasheets.raspberrypi.org/pico/raspberry-pi-pico-python-sdk.pdf
第17页

不过我将最后一句的延时时间改为0.005秒,让呼吸的速度慢一些。 程序运行后会让绿色LED呼吸闪烁4次

# Example using PWM to fade an LED.

import time
from machine import Pin, PWM

# Construct PWM object, with LED on Pin(25).
pwm = PWM(Pin(25))

# Set the PWM frequency.
pwm.freq(1000)

# Fade the LED in and out a few times.
duty = 0
direction = 1
for _ in range(8 * 256):
    duty += direction
    if duty > 255:
        duty = 255
        direction = -1
    elif duty < 0:
        duty = 0
        direction = 1
    pwm.duty_u16(duty * duty)
    time.sleep(0.005)

更进一步

我们再来尝试同时在几个GPIO产生不同频率、不同占空比的PWM。

在此之前,先说明几点树莓派Pico的PWM需要注意的地方:

  • 树莓派Pico一共有8个独立PWM引擎,被称为slices

  • 每一个slice有一个A通道和一个B通道可以输出PWM。

  • 不同的slice可以产生不同的频率,但是一个slice不同GPIO只能有一个相同的频率

  • A通道B通道可以有不同的占空比,但是一个slice一个通道的GPIO只能有相同的占空比

  • 需要注意,对PWM的设定会影响一个slice的所有GPIO

  • PWM的8个Slice对应的GPIO如下表:

Slice A B
0 0, 16 1, 17
1 2, 18 3, 19
2 4, 20 5, 21
3 6, 22 7, 23
4 8, 24 9, 25
5 10, 26 11, 27
6 12, 28 13, 29
7 14 15

在前面的博文可以看到,树莓派Pico核心板的绿色LED连接到GPIO25,而01Studio开发学习板的红、黄、蓝LED分别连接到GPIO18GPIO19GPIO20

GPIO25Slice 4GPIO18GPIO19Slice 1GPIO20Slice 2
也就是说,红色LED黄色LED只能有相同的闪烁频率,但是可以有不同的占空比,而绿色LED红色LED蓝色LED则可以有不同的闪烁频率。

import time
from machine import Pin, PWM

pwm_green  = PWM(Pin(25))
pwm_red    = PWM(Pin(18))
pwm_yellow = PWM(Pin(19))
pwm_blue   = PWM(Pin(20))

# 绿色LED闪烁频率 1000Hz
pwm_green.freq(1000)
# 红色LED闪烁频率 10Hz
pwm_red.freq(10)
# 黄色LED闪烁频率 10Hz
pwm_yellow.freq(10)
# 蓝色LED闪烁频率 20Hz
pwm_blue.freq(20)

# 绿色LED闪烁占空比 10%
pwm_green.duty_u16(6553)
# 红色LED闪烁占空比 1%
pwm_red.duty_u16(655)
# 黄色LED闪烁占空比 50%
pwm_yellow.duty_u16(32768)
# 蓝色LED闪烁占空比50%
pwm_blue.duty_u16(32768)

运行程序后可以看到:

  • 绿色LED因为闪烁频率是1000Hz,肉眼看不出闪烁,但是因为占空比只有10%,所以亮度比正常低很多;
  • 红色LED黄色LED的闪烁频率是一样的,但是红色LED的亮起时间明显短很多;
  • 蓝色LED的闪烁频率明显比红色LED黄色LED的快,但是还是肉眼可见的闪烁

此时,在 ThonnyShell 区域的命令提示行中尝试运行如下命令:

pwm_yellow.freq(100)

然后再运行

pwm_red.freq()

可以看到结果

>>> pwm_red.freq()
100

说明我们在更改黄色LED闪烁频率为100Hz时,红色LED的频率也变为100Hz了。

而观察开发板上的LED,也可以看出,此时红色LED黄色LED肉眼都看不出闪烁了,只是红色LED的亮度比黄色LED的亮度低很多,因为驱动红色LED的PWM的占空比只有1%。


版权声明:本文为zhufu86原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
THE END
< <上一篇
下一篇>>