klasa UART – dwukierunkowa magistrala komunikacji szeregowej

UART implementuje standardowy protokół dwukierunkowej komunikacji szeregowej UART/USART. Na poziomie fizycznym składa się z 2 linii: RX i TX. Jednostką komunikacji jest znak (nie mylić ze znakiem w łańcuchu), który może mieć szerokość 8 lub 9 bitów.

Obiekty UART można tworzyć i inicjalizować w następujący sposób:

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)

Liczba bitów może wynosić 7, 8 lub 9. Parzystość może mieć wartość None, 0 (parzysta) lub 1 (nieparzysta). Liczba bitów stopu może wynosić 1 lub 2.

Uwaga: przy parity=None obsługiwane są tylko 8 i 9 bitów. Przy włączonej parzystości obsługiwane są tylko 7 i 8 bitów.

Obiekt UART zachowuje się jak obiekt stream, a odczyt i zapis odbywają się przy użyciu standardowych metod strumieni:

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

Pojedyncze znaki można odczytywać/zapisywać w następujący sposób:

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

Aby sprawdzić, czy jest coś do odczytania, użyj:

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

Uwaga: Funkcje strumieni read, write itd. są nowością w MicroPython v1.3.4. Wcześniejsze wersje używają uart.send i uart.recv.

Konstruktory

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

Tworzy obiekt UART na podanej magistrali bus (całkowity indeks urządzenia peryferyjnego, np. 3 dla UART3). Bez dodatkowych parametrów obiekt jest tworzony, ale nie inicjalizowany (zachowuje poprzednie ustawienia magistrali, jeśli istnieją); jeśli podano dodatkowe argumenty, magistrala jest inicjalizowana. Dostępne parametry opisano w init().

UART(3) jest podłączony do tych samych pinów złącza na każdym OpenMV Cam ze STM32:

Sygnał

Pin złącza

TX

P4

RX

P5

Na niektórych płytkach dostępne są dodatkowe magistrale UART:

Magistrala

Pin TX

Pin RX

Dostępna na

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

Metody

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

Inicjalizuje magistralę UART z podanymi parametrami:

  • baudrate to częstotliwość zegara.

  • bits to liczba bitów na znak: 7, 8 lub 9.

  • parity to parzystość: None, 0 (parzysta) lub 1 (nieparzysta).

  • stop to liczba bitów stopu: 1 lub 2.

  • flow ustawia typ kontroli przepływu. Może mieć wartość 0, UART.RTS, UART.CTS lub UART.RTS | UART.CTS.

  • timeout to limit czasu w milisekundach na zapis/odczyt pierwszego znaku.

  • timeout_char to limit czasu w milisekundach pomiędzy znakami podczas zapisu lub odczytu.

  • read_buf_len to długość bufora odczytu wyrażona w znakach (0 wyłącza buforowanie).

Ta metoda zgłosi wyjątek, jeśli nie uda się ustawić szybkości transmisji (baud) w granicach 5% od żądanej wartości.

Uwaga: przy parity=None obsługiwane są tylko 8 i 9 bitów. Przy włączonej parzystości obsługiwane są tylko 7 i 8 bitów.

deinit() None

Wyłącza magistralę UART.

any() int

Zwraca liczbę oczekujących bajtów (może być 0).

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

Odczytuje znaki. Jeśli podano nbytes, odczytuje co najwyżej tyle bajtów. Jeśli w buforze dostępnych jest nbytes, zwraca natychmiast; w przeciwnym razie zwraca, gdy nadejdzie wystarczająca liczba znaków lub upłynie limit czasu.

Jeśli nbytes nie zostanie podane, metoda odczytuje tyle danych, ile to możliwe. Zwraca po upłynięciu limitu czasu.

Uwaga: dla znaków 9-bitowych każdy znak zajmuje dwa bajty, nbytes musi być parzyste, a liczba znaków wynosi nbytes/2.

Wartość zwracana: obiekt bytes zawierający wczytane bajty. Zwraca None po upłynięciu limitu czasu.

readchar() int

Odbiera pojedynczy znak z magistrali.

Wartość zwracana: odczytany znak jako liczba całkowita. Zwraca -1 po upłynięciu limitu czasu.

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

Odczytuje bajty do buf. Jeśli podano nbytes, odczytuje co najwyżej tyle bajtów. W przeciwnym razie odczytuje co najwyżej len(buf) bajtów.

Wartość zwracana: liczba bajtów odczytanych i zapisanych do buf lub None po upłynięciu limitu czasu.

readline() bytes | None

Odczytuje wiersz zakończony znakiem nowej linii. Jeśli taki wiersz istnieje, zwrot następuje natychmiast. Jeśli upłynie limit czasu, zwracane są wszystkie dostępne dane, niezależnie od tego, czy znak nowej linii istnieje.

Wartość zwracana: odczytany wiersz lub None po upłynięciu limitu czasu, jeśli brak dostępnych danych.

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

Zapisuje bufor bajtów do magistrali. Jeśli znaki mają szerokość 7 lub 8 bitów, każdy bajt to jeden znak. Jeśli znaki mają szerokość 9 bitów, na każdy znak przypadają dwa bajty (little endian), a buf musi zawierać parzystą liczbę bajtów.

Wartość zwracana: liczba zapisanych bajtów. Jeśli wystąpi przekroczenie limitu czasu i nie zapisano żadnych bajtów, zwraca None.

writechar(char: int) None

Zapisuje pojedynczy znak na magistrali. char to liczba całkowita do zapisania. Zobacz sekcję CTS flow control poniżej, aby poznać semantykę blokowania przy włączonej kontroli przepływu CTS.

sendbreak() None

Wysyła warunek przerwania (break) na magistrali. Powoduje to ustawienie magistrali w stan niski na czas trwania 13 bitów.

Stałe

RTS: int

Flaga bitowa dla argumentu flow metody init(); włącza sprzętową kontrolę przepływu RTS (request-to-send) na ścieżce odbioru.

CTS: int

Flaga bitowa dla argumentu flow metody init(); włącza sprzętową kontrolę przepływu CTS (clear-to-send) na ścieżce nadawania. Można ją połączyć operatorem OR z RTS, aby włączyć oba kierunki.

Kontrola przepływu

UART(3) obsługuje sprzętową kontrolę przepływu RTS/CTS. Na OpenMV Cam M7, H7, H7 Plus i Pure Thermal piny kontroli przepływu to:

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

Na OpenMV Cam N6 udostępniony jest tylko nRTS (na pinie złącza P7); nCTS nie jest wyprowadzony na złącze I/O.

W poniższych akapitach termin „target” odnosi się do urządzenia podłączonego do UART.

Gdy metoda init() obiektu UART zostanie wywołana z flow ustawionym na jedną lub obie z wartości UART.RTS i UART.CTS, konfigurowane są odpowiednie piny kontroli przepływu. nRTS to wyjście aktywne w stanie niskim, a nCTS to wejście aktywne w stanie niskim z włączonym podciąganiem (pull-up). Aby podłączyć kontrolę przepływu, połącz nCTS OpenMV Cam z nRTS urządzenia docelowego, a nRTS OpenMV Cam z nCTS urządzenia docelowego.

CTS: urządzenie docelowe steruje nadajnikiem OpenMV Cam

Jeśli kontrola przepływu CTS jest włączona, zachowanie przy zapisie jest następujące:

Jeśli wywołana zostanie metoda UART.write(buf) OpenMV Cam, transmisja zostanie wstrzymana na każdy okres, gdy nCTS ma wartość False. Spowoduje to przekroczenie limitu czasu, jeśli cały bufor nie zostanie przesłany w wyznaczonym czasie. Metoda zwraca liczbę zapisanych bajtów, umożliwiając użytkownikowi zapisanie pozostałej części danych, jeśli to konieczne. W przypadku przekroczenia limitu czasu jeden znak pozostanie w UART w oczekiwaniu na nCTS. Liczba bajtów składających się na ten znak zostanie uwzględniona w wartości zwracanej.

Jeśli UART.writechar() zostanie wywołane, gdy nCTS ma wartość False, metoda przekroczy limit czasu, chyba że urządzenie docelowe ustawi nCTS na czas. Jeśli limit czasu zostanie przekroczony, zgłoszony zostanie OSError 116. Znak zostanie przesłany, gdy tylko urządzenie docelowe ustawi nCTS.

RTS: OpenMV Cam steruje nadajnikiem urządzenia docelowego

Jeśli kontrola przepływu RTS jest włączona, zachowanie jest następujące:

Jeśli używane jest buforowane wejście (read_buf_len > 0), przychodzące znaki są buforowane. Jeśli bufor się zapełni, kolejny przychodzący znak spowoduje ustawienie nRTS na False: urządzenie docelowe powinno przerwać transmisję. nRTS przejdzie w stan True, gdy znaki zostaną odczytane z bufora.

Zwróć uwagę, że metoda any() zwraca liczbę bajtów w buforze. Załóżmy, że długość bufora wynosi N bajtów. Jeśli bufor się zapełni i nadejdzie kolejny znak, nRTS zostanie ustawiony na False, a any() zwróci wartość N. Gdy znaki zostaną odczytane, dodatkowy znak zostanie umieszczony w buforze i uwzględniony w wyniku kolejnego wywołania any().

Jeśli buforowane wejście nie jest używane (read_buf_len == 0), nadejście znaku spowoduje ustawienie nRTS na False, dopóki znak nie zostanie odczytany.