class UART -- 雙工序列通訊匯流排

UART 實作標準的 UART/USART 雙工序列通訊協定。在實體層上,它由兩條線組成:RX 與 TX。通訊的單位是一個字元(請勿與字串字元混淆),其寬度可為 8 或 9 位元。

UART 物件可使用以下方式建立並初始化::

from pyb import UART

# init with the given baudrate
uart = UART(3, 9600, timeout_char=1000)

# init with explicit parameters
uart.init(9600, bits=8, parity=None, stop=1, timeout_char=1000)

Bits 可為 7、8 或 9。Parity 可為 None、0(偶同位)或 1(奇同位)。Stop 可為 1 或 2。

注意: 當 parity=None 時,僅支援 8 與 9 位元。啟用同位檢查時,僅支援 7 與 8 位元。

UART 物件的行為類似 stream 物件,讀取與寫入可使用標準的串流方法完成::

uart.read(10)       # read 10 characters, returns a bytes object
uart.read()         # read all available characters
uart.readline()     # read a line
uart.readinto(buf)  # read and store into the given buffer
uart.write('abc')   # write the 3 characters

個別字元可使用以下方式讀取/寫入::

uart.readchar()     # read 1 character and returns it as an integer
uart.writechar(42)  # write 1 character

若要檢查是否有任何資料可供讀取,請使用::

uart.any()          # returns the number of characters waiting

注意: 串流函式 readwrite 等是 MicroPython v1.3.4 新增的。較早的版本使用 uart.senduart.recv

建構子

class pyb.UART(bus: int | str, *args, **kwargs)

在指定的 bus(整數周邊裝置索引,例如 3 代表 UART3)上建構一個 UART 物件。若未提供額外參數,則建立物件但不初始化(它會保留先前的匯流排設定,若有的話);若提供額外引數,則會初始化匯流排。可用參數請參閱 init()

UART(3) 在每一款 STM32 OpenMV Cam 上都接到相同的排針接腳:

訊號

排針接腳

TX

P4

RX

P5

某些開發板上還有額外的 UART 匯流排可用:

匯流排

TX 接腳

RX 接腳

可用於

UART(1)

P1

P0

OpenMV Cam M7 / H7 / H7 Plus / Pure Thermal

UART(4)

P2

P3

OpenMV Cam N6

UART(7)

P14

P13

OpenMV Cam N6

方法

init(baudrate: int, bits: int = 8, parity: int | None = None, stop: int = 1, *, timeout: int = 1000, flow: int = 0, timeout_char: int = 0, read_buf_len: int = 64) None

以指定的參數初始化 UART 匯流排:

  • baudrate 是時脈速率。

  • bits 是每個字元的位元數,7、8 或 9。

  • parity 是同位檢查,None、0(偶同位)或 1(奇同位)。

  • stop 是停止位元數,1 或 2。

  • flow 設定流量控制類型。可為 0、UART.RTSUART.CTSUART.RTS | UART.CTS

  • timeout 是等待寫入/讀取第一個字元的逾時時間(以毫秒為單位)。

  • timeout_char 是寫入或讀取時,字元之間等待的逾時時間(以毫秒為單位)。

  • read_buf_len 是讀取緩衝區的字元長度(設為 0 則停用)。

若鮑率無法設定在期望值的 5% 範圍內,此方法將引發例外。

注意: 當 parity=None 時,僅支援 8 與 9 位元。啟用同位檢查時,僅支援 7 與 8 位元。

deinit() None

關閉 UART 匯流排。

any() int

傳回正在等待的位元組數(可能為 0)。

read(nbytes: int | None = None) bytes | None

讀取字元。若指定了 nbytes,則最多讀取那麼多位元組。若緩衝區中已有 nbytes 個位元組可用,則立即傳回,否則在足夠的字元到達或逾時經過時傳回。

若未提供 nbytes,則此方法會讀取盡可能多的資料。它會在逾時經過後傳回。

注意: 對於 9 位元字元,每個字元佔兩個位元組,nbytes 必須為偶數,字元數為 nbytes/2

傳回值:包含所讀入位元組的 bytes 物件。逾時時傳回 None

readchar() int

在匯流排上接收單一字元。

傳回值:所讀取的字元,以整數表示。逾時時傳回 -1。

readinto(buf: bytearray, nbytes: int | None = None) int | None

將位元組讀入 buf。若指定了 nbytes,則最多讀取那麼多位元組。否則,最多讀取 len(buf) 個位元組。

傳回值:讀取並儲存到 buf 的位元組數,逾時時為 None

readline() bytes | None

讀取一行,以換行字元結尾。若存在這樣的一行,則立即傳回。若逾時經過,則無論是否存在換行字元,皆傳回所有可用的資料。

傳回值:所讀取的行,若無資料可用而逾時則為 None

write(buf: bytes | bytearray | str) int | None

將位元組緩衝區寫入匯流排。若字元寬度為 7 或 8 位元,則每個位元組為一個字元。若字元寬度為 9 位元,則每個字元使用兩個位元組(小端序),且 buf 必須包含偶數個位元組。

傳回值:所寫入的位元組數。若發生逾時且未寫入任何位元組,則傳回 None

writechar(char: int) None

在匯流排上寫入單一字元。char 是要寫入的整數。當啟用 CTS 流量控制時的阻塞語意,請參閱下方的 CTS 流量控制 章節。

sendbreak() None

在匯流排上送出中斷(break)狀態。這會將匯流排拉低 13 個位元的時間長度。

常數

RTS: int

用於 init()flow 引數的位元旗標;在接收路徑上啟用 RTS(request-to-send,要求傳送)硬體流量控制。

CTS: int

用於 init()flow 引數的位元旗標;在傳送路徑上啟用 CTS(clear-to-send,允許傳送)硬體流量控制。可與 RTS 進行 OR 運算以同時啟用兩個方向。

流量控制

UART(3) 支援 RTS/CTS 硬體流量控制。在 OpenMV Cam M7、H7、H7 Plus 與 Pure Thermal 上,流量控制接腳為:

(TX, RX, nRTS, nCTS) = (P4, P5, P1, P2)

在 OpenMV Cam N6 上僅暴露 nRTS(位於排針接腳 P7);nCTS 並未接到 I/O 排針上。

在以下段落中,「目標」一詞指的是連接到 UART 的裝置。

當呼叫 UART 的 init() 方法且 flow 設為 UART.RTSUART.CTS 其中之一或兩者時,相關的流量控制接腳會被設定。nRTS 是低電位有效的輸出,nCTS 是低電位有效並啟用上拉的輸入。若要接好流量控制,請將 OpenMV Cam 的 nCTS 連接到目標的 nRTS,並將 OpenMV Cam 的 nRTS 連接到目標的 nCTS

CTS:目標控制 OpenMV Cam 的傳送器

若啟用 CTS 流量控制,寫入行為如下:

若呼叫 OpenMV Cam 的 UART.write(buf) 方法,傳送會在 nCTSFalse 的任何期間停滯。如果在逾時期間內未傳送完整個緩衝區,這將導致逾時。此方法會傳回所寫入的位元組數,使使用者能在需要時寫入剩餘的資料。在逾時的情況下,會有一個字元留在 UART 中等待 nCTS。組成此字元的位元組數會包含在傳回值中。

若在 nCTSFalse 時呼叫 UART.writechar(),除非目標及時表明 nCTS,否則此方法會逾時。若逾時,將引發 OSError 116。一旦目標表明 nCTS,該字元便會立即被傳送。

RTS:OpenMV Cam 控制目標的傳送器

若啟用 RTS 流量控制,行為如下:

若使用緩衝輸入(read_buf_len > 0),傳入的字元會被緩衝。若緩衝區變滿,下一個到達的字元會使 nRTS 變為 False:目標應停止傳送。當從緩衝區讀取字元時,nRTS 會變為 True

請注意,any() 方法會傳回緩衝區中的位元組數。假設緩衝區長度為 N 個位元組。若緩衝區變滿,且又有另一個字元到達,nRTS 會被設為 False,而 any() 會傳回計數 N。當讀取字元時,那個額外的字元會被放入緩衝區,並會包含在後續 any() 呼叫的結果中。

若未使用緩衝輸入(read_buf_len == 0),字元的到達會使 nRTS 變為 False,直到該字元被讀取為止。