天天看點

我用樹莓派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%。