天天看点

我用树莓派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)
           

运行这段程序后,可以看到

绿色LED

以10Hz的频率快速闪烁(树莓派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, 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

分别连接到

GPIO18

GPIO19

GPIO20

GPIO25

Slice 4

GPIO18

GPIO19

Slice 1

GPIO20

Slice 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

    的快,但是还是肉眼可见的闪烁

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

pwm_yellow.freq(100)
           

然后再运行

pwm_red.freq()
           

可以看到结果

>>> pwm_red.freq()
100
           

说明我们在更改

黄色LED

闪烁频率为100Hz时,

红色LED

的频率也变为100Hz了。

而观察开发板上的LED,也可以看出,此时

红色LED

黄色LED

肉眼都看不出闪烁了,只是

红色LED

的亮度比

黄色LED

的亮度低很多,因为驱动

红色LED

的PWM的占空比只有1%。