klasa I2C – dwuprzewodowy protokół szeregowy¶
I2C to dwuprzewodowy protokół do komunikacji między urządzeniami. Na poziomie fizycznym składa się z 2 przewodów: SCL i SDA, odpowiednio linii zegara i danych.
Obiekty I2C są tworzone jako przypisane do określonej magistrali. Mogą zostać zainicjalizowane podczas tworzenia lub później.
Wydrukowanie obiektu I2C dostarcza informacji o jego konfiguracji.
Istnieją implementacje I2C zarówno sprzętowe, jak i programowe, dostępne za pośrednictwem klas I2C i SoftI2C. Sprzętowe I2C wykorzystuje wbudowane wsparcie sprzętowe systemu do wykonywania odczytów/zapisów i jest zwykle wydajne i szybkie, ale może mieć ograniczenia co do tego, których pinów można używać. Programowe I2C jest realizowane techniką bit-banging i może być używane na dowolnym pinie, lecz nie jest tak wydajne. Klasy te udostępniają te same metody i różnią się głównie sposobem konstruowania.
Informacja
Do działania magistrala I2C wymaga obwodu podciągającego (pull-up) na obu liniach SDA i SCL. Zazwyczaj są to rezystory w zakresie 1 - 10 kOhm, podłączone od każdej z linii SDA/SCL do Vcc. Bez nich zachowanie jest nieokreślone i może obejmować zarówno blokowanie, nieoczekiwany reset watchdoga, jak i po prostu błędne wartości. Często ten obwód podciągający jest już wbudowany w płytkę MCU lub moduły rozszerzające z sensorami, ale nie jest to regułą. Dlatego w razie problemów należy to sprawdzić. Zobacz także ten doskonały przewodnik firmy Adafruit dotyczący okablowania I2C.
Przykład użycia:
from machine import I2C
i2c = I2C(freq=400000) # create I2C peripheral at frequency of 400kHz
# depending on the port, extra parameters may be required
# to select the peripheral and/or pins to use
i2c.scan() # scan for peripherals, returning a list of 7-bit addresses
i2c.writeto(42, b'123') # write 3 bytes to peripheral with 7-bit address 42
i2c.readfrom(42, 4) # read 4 bytes from peripheral with 7-bit address 42
i2c.readfrom_mem(42, 8, 3) # read 3 bytes from memory of peripheral 42,
# starting at memory-address 8 in the peripheral
i2c.writeto_mem(42, 2, b'\x10') # write 1 byte to memory of peripheral 42
# starting at address 2 in the peripheral
Konstruktory¶
- class machine.I2C(id: int, *, scl: Pin | None = None, sda: Pin | None = None, freq: int = 400000, timeout: int = 50000)¶
Konstruuje i zwraca nowy obiekt I2C, używając następujących parametrów:
id identyfikuje konkretne urządzenie peryferyjne I2C. Dozwolone wartości zależą od konkretnego portu/płytki
scl powinien być obiektem pinu określającym pin używany dla SCL.
sda powinien być obiektem pinu określającym pin używany dla SDA.
freq powinno być liczbą całkowitą ustawiającą maksymalną częstotliwość dla SCL.
timeout to maksymalny czas w mikrosekundach dozwolony dla transakcji I2C. Ten parametr nie jest dozwolony na niektórych portach.
Należy zauważyć, że niektóre porty/płytki będą miały domyślne wartości scl i sda, które można zmienić w tym konstruktorze. Inne będą miały stałe wartości scl i sda, których nie można zmienić.
Metody ogólne¶
- init(scl: Pin, sda: Pin, *, freq: int = 400000) None¶
Inicjalizuje magistralę I2C z podanymi argumentami:
scl to obiekt pinu dla linii SCL
sda to obiekt pinu dla linii SDA
freq to częstotliwość zegara SCL
W przypadku sprzętowego I2C rzeczywista częstotliwość zegara może być niższa niż żądana. Zależy to od sprzętu platformy. Rzeczywistą szybkość można ustalić, drukując obiekt I2C.
Podstawowe operacje I2C¶
Poniższe metody implementują podstawowe operacje magistrali kontrolera I2C i można je łączyć, aby zrealizować dowolną transakcję I2C. Są one dostarczane na wypadek, gdy potrzebujesz większej kontroli nad magistralą; w przeciwnym razie można używać metod standardowych (patrz niżej).
Te metody są dostępne wyłącznie w klasie
SoftI2C.- start() None¶
Generuje na magistrali warunek START (SDA przechodzi w stan niski, gdy SCL jest w stanie wysokim).
- stop() None¶
Generuje na magistrali warunek STOP (SDA przechodzi w stan wysoki, gdy SCL jest w stanie wysokim).
- readinto(buf: bytearray, nack: bool = True, /) None¶
Odczytuje bajty z magistrali i zapisuje je do buf. Liczba odczytanych bajtów to długość buf. Po odebraniu wszystkich bajtów oprócz ostatniego na magistralę zostanie wysłany ACK. Po odebraniu ostatniego bajtu, jeśli nack jest prawdą, zostanie wysłany NACK, w przeciwnym razie zostanie wysłany ACK (w tym przypadku urządzenie peryferyjne zakłada, że kolejne bajty zostaną odczytane w późniejszym wywołaniu).
Standardowe operacje na magistrali¶
Poniższe metody implementują standardowe operacje odczytu i zapisu kontrolera I2C skierowane do danego urządzenia peryferyjnego.
- readfrom(addr: int, nbytes: int, stop: bool = True, /) bytes¶
Odczytuje nbytes z urządzenia peryferyjnego określonego przez addr. Jeśli stop jest prawdą, na końcu transferu generowany jest warunek STOP. Zwraca obiekt
bytesz odczytanymi danymi.
- readfrom_into(addr: int, buf: bytearray, stop: bool = True, /) None¶
Odczytuje do buf z urządzenia peryferyjnego określonego przez addr. Liczba odczytanych bajtów będzie równa długości buf. Jeśli stop jest prawdą, na końcu transferu generowany jest warunek STOP.
Metoda zwraca
None.
- writeto(addr: int, buf: bytes, stop: bool = True, /) int¶
Zapisuje bajty z buf do urządzenia peryferyjnego określonego przez addr. Jeśli po zapisie bajtu z buf odebrany zostanie NACK, pozostałe bajty nie są wysyłane. Jeśli stop jest prawdą, na końcu transferu generowany jest warunek STOP, nawet jeśli odebrano NACK. Funkcja zwraca liczbę odebranych ACK.
- writevto(addr: int, vector: tuple | list, stop: bool = True, /) int¶
Zapisuje bajty zawarte w vector do urządzenia peryferyjnego określonego przez addr. vector powinien być krotką lub listą obiektów obsługujących protokół buforów. addr jest wysyłany raz, a następnie bajty z każdego obiektu w vector są zapisywane kolejno. Obiekty w vector mogą mieć zerową długość, w którym to przypadku nie wnoszą nic do wyjścia.
Jeśli po zapisie bajtu z jednego z obiektów w vector odebrany zostanie NACK, pozostałe bajty oraz wszelkie pozostałe obiekty nie są wysyłane. Jeśli stop jest prawdą, na końcu transferu generowany jest warunek STOP, nawet jeśli odebrano NACK. Funkcja zwraca liczbę odebranych ACK.
Operacje na pamięci¶
Niektóre urządzenia I2C działają jak urządzenia pamięciowe (lub zestawy rejestrów), z których można odczytywać i do których można zapisywać. W takim przypadku z transakcją I2C powiązane są dwa adresy: adres urządzenia peryferyjnego oraz adres pamięci. Poniższe metody to funkcje pomocnicze do komunikacji z takimi urządzeniami.
- readfrom_mem(addr: int, memaddr: int, nbytes: int, *, addrsize: int = 8) bytes¶
Odczytuje nbytes z urządzenia peryferyjnego określonego przez addr, zaczynając od adresu pamięci określonego przez memaddr. Argument addrsize określa rozmiar adresu w bitach. Zwraca obiekt
bytesz odczytanymi danymi.
- readfrom_mem_into(addr: int, memaddr: int, buf: bytearray, *, addrsize: int = 8) None¶
Odczytuje do buf z urządzenia peryferyjnego określonego przez addr, zaczynając od adresu pamięci określonego przez memaddr. Liczba odczytanych bajtów to długość buf. Argument addrsize określa rozmiar adresu w bitach.
Metoda zwraca
None.
klasa SoftI2C – programowo emulowana magistrala I2C¶
Klasa SoftI2C implementuje I2C poprzez bit-banging dowolnych pinów GPIO. Udostępnia ten sam zestaw metod co I2C oraz dodatkowo niskopoziomowe podstawowe operacje magistrali (start(), stop(), readinto(), write()) dla wywołujących, którzy muszą złożyć niestandardowe transakcje. Używaj jej, gdy potrzebne piny nie są podłączone do sprzętowego bloku I2C, gdy potrzebujesz większej liczby magistral niż zapewnia sprzęt, lub aby komunikować się z urządzeniami wymagającymi nietypowych sekwencji (dodatkowe takty zegara, powtarzane starty po zapisach itp.).
Konstruktory¶
- class machine.SoftI2C(scl: Pin, sda: Pin, *, freq: int = 400000, timeout: int = 50000)¶
Konstruuje programową magistralę I2C sterowaną przez
scl/sda.freqto docelowa szybkość zegara SCL w Hz (rzeczywista szybkość jest zazwyczaj niższa ze względu na narzut pętli bit-bang).timeoutto maksymalny czas w mikrosekundach oczekiwania na rozciąganie zegara (clock stretching) (SCL przytrzymane w stanie niskim przez inne urządzenie na magistrali); po jego upływie zgłaszany jestOSError(ETIMEDOUT).Metody ogólne¶
Podstawowe operacje I2C¶
Poniższe metody implementują podstawowe operacje magistrali kontrolera I2C i można je łączyć, aby zrealizować dowolną transakcję I2C. Są one dostępne wyłącznie w SoftI2C – sprzętowa klasa
I2Cich nie udostępnia.- start() None¶
Generuje na magistrali warunek START (SDA przechodzi w stan niski, gdy SCL jest w stanie wysokim).
- stop() None¶
Generuje na magistrali warunek STOP (SDA przechodzi w stan wysoki, gdy SCL jest w stanie wysokim).
- readinto(buf: bytearray, nack: bool = True, /) None¶
Odczytuje bajty z magistrali do
buf. Odczytywane jestlen(buf)bajtów; po każdym bajcie oprócz ostatniego wysyłany jest ACK. Po ostatnim bajcienack=True(wartość domyślna) wysyła NACK kończący transfer;nack=Falsewysyła ACK, dzięki czemu urządzenie pozostaje wybrane na potrzeby kolejnegoreadinto().
Standardowe operacje na magistrali¶
Poniższe metody implementują standardowe operacje odczytu i zapisu kontrolera I2C skierowane do danego urządzenia peryferyjnego.
- readfrom(addr: int, nbytes: int, stop: bool = True, /) bytes¶
Odczytuje
nbytesz urządzenia o 7-bitowym adresieaddr. Jeślistopjest prawdą, na końcu transferu generowany jest warunek STOP.
- readfrom_into(addr: int, buf: bytearray, stop: bool = True, /) None¶
Odczytuje
len(buf)bajtów z urządzenia o adresieaddrdobuf. Jeślistopjest prawdą, na końcu transferu generowany jest warunek STOP.
Operacje na pamięci¶
Niektóre urządzenia I2C działają jak urządzenia pamięciowe (lub zestawy rejestrów), z których można odczytywać i do których można zapisywać. W takim przypadku z transakcją I2C powiązane są dwa adresy: adres urządzenia peryferyjnego oraz adres pamięci. Poniższe metody to pomocnicze funkcje ułatwiające komunikację z takimi urządzeniami.
- readfrom_mem(addr: int, memaddr: int, nbytes: int, *, addrsize: int = 8) bytes¶
Odczytuje
nbytesz urządzenia o adresieaddr, zaczynając od rejestrumemaddr.addrsizeto szerokość adresu rejestru w bitach (zazwyczaj8lub16).