- 什麼是串列埠
- 使用方法
- 使用板載串列埠相互通訊
- 硬體需求
- 電路
- 程式碼
- 使用板載的 USB 串列埠
- 參考
什麼是串列埠
串列埠是序列介面的簡稱,這是一個非常大的概念,在嵌入式中串列埠通常指 UART(Universal Asynchronous Receiver/Transmitter,通用非同步收發器)。使用串列埠進行的通訊叫做序列通訊,與之相對的一個概念是並行通訊。序列通訊是指資料一位一位的按順序傳輸,而並行通訊則是多位資料同時傳輸。如下圖所示,DATA BUS
到 UART 1
之間是並行通訊,UART 1
到 UART 2
之間是序列通訊。
串列埠通訊的資料幀格式如下圖所示,通常一幀共包括 10 位:1 個起始位,8 個資料位和 1 個停止位。有一些特殊的資料幀在停止位前面包含 1 位的奇偶校驗位,還有的停止位有 2 個位元。其中起始位為低電平(0),標誌著資料傳輸的開始;停止位為高電平(1),表示資料幀傳輸結束;資料位則為實際傳送的資料,使用高低電平來表示二進位制資訊,如果傳送的內容是文字,那麼這段資料為字元的二進位制編碼(ASCII、UTF-8等)。資料傳輸的速率我們使用波特率(Baud Rate)來表示,即每秒鐘傳送的碼元符號的個數。比如資料傳輸速率為 9600 字元/s,那麼這時的波特率為 9600。
裝置進行串列埠通訊時,裝置的連線如下圖所示,兩個裝置的訊號線,即傳送端(TXD)與接收端(RXD)交叉相連,並且需要共地。在 Raspberry Pi Pico 的引腳上共引出了 2 組串列埠,即 UART0
與 UART1
。
使用方法
使用 MicroPython 控制 GPIO 要使用 machine
包中的 UART
類。
from machine import UART
透過建構函式例項化獲取串列埠物件。
UART(id: int, baudrate: int = 115200, ...)
id
指串列埠的編號。對於 Pico 而言只能是 0 或 1。baudrate
用於設定波特率。tx
、rx
引數指定要使用的 tx、rx 引腳。parity
設定校驗位。None
無,0
偶數,1
奇數。stop
設定停止位的長度。timeout
設定讀取超時時間,單位為毫秒。
使用 init()
方法可以修改串列埠的設定,方法引數與建構函式的引數一致。常見的用法參考下面的例子:
uart0 = UART(0, 9600) # 例項化串列埠 0,波特率為 9600
uart0.init(115200, bits=8, parity=None, stop=1) # 修改串列埠 0 設定
uart1 = UART(1, baudrate=9600, tx=Pin(8), rx=Pin(9)) # 例項化串列埠 1 並指定引腳
例項化串列埠物件後,使用 write(buf: bytearray)
方法傳送資料,傳送成功會返回位元組數,失敗則返回 None
。
data = b'hello world'
uart0.write(data)
接收資料使用 read(nbytes: Optional[int] = None)
方法,nbytes
設定接收的位元組數,讀取成功會返回一個位元組物件,讀取超時則返回 None
。也可以使用 readline()
方法讀取一行。
data = bytes()
data = uart0.read(10)
print(data.decode('utf-8')) # 解碼成 utf-8 字串
print(uart0.readline()) # 從串列埠讀取一行
有些時候需要判斷串列埠中有沒有資料,可以使用 any()
方法。
while uart0.any() > 0:
print(uart0.readline())
💡 提示
在部分開發板上可以像 GPIO 中斷一樣,使用串列埠中斷 irq(trigger, priority=1, handler=None, wake=machine.IDLE)
使用 deinit()
方法可關閉串列埠。
uart0.deinit()
使用板載串列埠相互通訊
Pico 上有兩組串列埠 UART0
與 UART1
,因此可以使用這兩組串列埠相互通訊。
硬體需求
名稱 | 數量 |
---|---|
杜邦線 | 若干 |
電路
- UART0 RX(GP1) - UART1 TX(GP4)
- UART0 TX(GP0) - UART1 RX(GP5)
程式碼
from machine import UART, Pin
import utime
# 初始化串列埠
uart0 = UART(0, baudrate=9600, tx=Pin(0), rx=Pin(1))
uart1 = UART(1, baudrate=9600, tx=Pin(4), rx=Pin(5))
# 串列埠 1 傳送資料
txData = b'hello world'
uart1.write(txData)
utime.sleep_ms(100)
# 串列埠 2 檢測接收資料
rxData = bytes()
while uart0.any() > 0:
rxData += uart0.read(1)
# 解碼並列印
print(rxData.decode('utf-8'))
使用板載的 USB 串列埠
當 Pico 連線到計算機上時,在裝置管理器中會新增一個通訊埠 COMx
,MicroPython 的 REPL 終端就是執行在這個串列埠之上。那麼能使用這個板載 USB 串列埠傳輸資料嗎?答案是可以的,但與正常串列埠通訊的程式碼不同,需要使用 select
,一個用於非同步 I/O 多路複用的模組。將下面的程式碼燒錄到 Pico 中,使用 PuTTY
等串列埠工具連線 Pico,當 Pico 檢測到輸入 1
時點亮板載 LED,輸入 0
時熄滅。
import machine
import select
import sys
led = machine.Pin('LED', machine.Pin.OUT)
# 獲取複用的輪詢物件
poll_object = select.poll()
# 將系統標準輸入註冊為輪詢物件
poll_object.register(sys.stdin, 1)
while True:
# 檢查 USB 串列埠輸入
if poll_object.poll(0):
# 從 USB 串列埠中讀取
ch = sys.stdin.read(1)
if ch == '1'
led.value(1)
# 向 USB 串列埠中寫入
print("LED ON")
else
led.value(0)
print("LED OFF")
參考
- Universal asynchronous receiver-transmitter - Wikipedia:https://en.wikipedia.org/wiki/Universal_asynchronous_receiver-transmitter
- Serial Communication - Wikipedia:https://en.wikipedia.org/wiki/Serial_communication
- BASICS OF UART COMMUNICATION:http://www.circuitbasics.com/basics-uart-communication/
- 波特率 - 百度百科:https://baike.baidu.com/item/波特率
- MicroPython documentation:https://docs.micropython.org/en/latest/library/machine.UART.html