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通道
可以輸出PWM。B通道
- 不同的
可以産生不同的頻率,但是一個slice
的不同GPIO隻能有一個相同的頻率slice
-
和A通道
可以有不同的占空比,但是一個B通道
的一個通道的GPIO隻能有slice
的占空比相同
- 需要注意,對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)
運作程式後可以看到:
-
因為閃爍頻率是1000Hz,肉眼看不出閃爍,但是因為占空比隻有10%,是以亮度比正常低很多;綠色LED
-
和紅色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%。