klasa I2C – dwuprzewodowy protokół szeregowy

I2C to dwuprzewodowy protokół do komunikacji między urządzeniami. Na poziomie fizycznym składa się z dwóch linii: SCL (zegar) i SDA (dane). OpenMV Cam nie zapewnia wbudowanych rezystorów podciągających na żadnej z tych linii – aby magistrala działała, wymagane są zewnętrzne rezystory podciągające na obu liniach SCL i SDA.

Obiekty I2C są przypisane do określonej magistrali i mogą być inicjalizowane w momencie tworzenia lub później za pomocą init().

Przykład:

from pyb import I2C

i2c = I2C(2)                              # create on bus 2 (uninitialised)
i2c = I2C(2, I2C.CONTROLLER)              # create and init as a controller
i2c.init(I2C.CONTROLLER, baudrate=20000)  # init as a controller
i2c.init(I2C.PERIPHERAL, addr=0x42)       # init as a peripheral with the given address
i2c.deinit()                              # turn off the peripheral

Wyświetlenie obiektu I2C pokazuje jego konfigurację.

Podstawowe metody to send() i recv()

i2c.send("abc")      # send 3 bytes
i2c.send(0x42)       # send a single byte, given by the number
data = i2c.recv(3)   # receive 3 bytes

Aby odebrać dane w miejscu, najpierw utwórz bytearray

data = bytearray(3)  # create a buffer
i2c.recv(data)       # receive 3 bytes, writing them into data

Możesz określić limit czasu (w ms):

i2c.send(b"123", timeout=2000)   # timeout after 2 seconds

Kontroler musi określić adres odbiorcy:

i2c.init(I2C.CONTROLLER)
i2c.send("123", 0x42)        # send 3 bytes to peripheral with address 0x42
i2c.send(b"456", addr=0x42)  # keyword for address

Kontroler posiada również następujące metody:

# Check if peripheral 0x42 is ready.
i2c.is_ready(0x42)

# Scan the bus and return a list of responding addresses.
i2c.scan()

# Read 3 bytes from peripheral 0x42 starting at memaddr 2.
i2c.mem_read(3, 0x42, 2)

# Write 3 bytes to peripheral 0x42 at memaddr 2.
i2c.mem_write("abc", 0x42, 2, timeout=1000)

Konstruktory

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

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

I2C(2) jest podłączone do tych samych pinów złącza w każdej kamerze OpenMV Cam udostępniającej pyb.I2C (M4 / M7 / H7 / H7 Plus / Pure Thermal):

Sygnał

Pin złącza

Uwagi

SCL

P4

SDA

P5

I2C(4) jest dodatkowo dostępne w kamerach OpenMV Cam M7, H7, H7 Plus i Pure Thermal, z SCL na pinie złącza P7 oraz SDA na pinie złącza P8.

OpenMV Cam N6 nie udostępnia pyb.I2C; zamiast tego użyj machine.I2C.

Metody

deinit() None

Wyłącza magistralę I2C.

init(mode: int, *, addr: int = 0x12, baudrate: int = 400000, gencall: bool = False, dma: bool = False) None

Inicjalizuje magistralę I2C z zadanymi parametrami:

  • mode musi przyjmować wartość I2C.CONTROLLER lub I2C.PERIPHERAL.

  • addr to 7-bitowy adres (sensowny tylko dla urządzenia peryferyjnego).

  • baudrate to szybkość zegara SCL (sensowna tylko dla kontrolera).

  • gencall określa, czy obsługiwać tryb wywołania ogólnego (general-call).

  • dma określa, czy zezwolić na użycie DMA w transferach I2C (zauważ, że transfery DMA mają bardziej precyzyjne taktowanie, ale obecnie nie obsługują poprawnie błędów magistrali).

Rzeczywista częstotliwość zegara może być niższa niż żądana. Zależy to od sprzętu danej platformy. Rzeczywistą szybkość można ustalić, wyświetlając obiekt I2C.

is_ready(addr: int) bool

Sprawdza, czy urządzenie I2C odpowiada pod zadanym adresem. Prawidłowe tylko w trybie kontrolera.

mem_read(data: int | bytearray, addr: int, memaddr: int, *, timeout: int = 5000, addr_size: int = 8) bytes

Odczytuje z pamięci urządzenia I2C:

  • data może być liczbą całkowitą (liczba bajtów do odczytu) lub buforem, do którego nastąpi odczyt

  • addr to adres urządzenia I2C

  • memaddr to lokalizacja w pamięci wewnątrz urządzenia I2C

  • timeout to limit czasu w milisekundach oczekiwania na odczyt

  • addr_size wybiera szerokość memaddr: 8 lub 16 bitów

Zwraca odczytane dane. Prawidłowe tylko w trybie kontrolera.

mem_write(data: int | bytes | bytearray, addr: int, memaddr: int, *, timeout: int = 5000, addr_size: int = 8) None

Zapisuje do pamięci urządzenia I2C:

  • data może być liczbą całkowitą lub buforem, z którego nastąpi zapis.

  • addr to adres urządzenia I2C.

  • memaddr to lokalizacja w pamięci wewnątrz urządzenia I2C.

  • timeout to limit czasu w milisekundach oczekiwania na zapis.

  • addr_size wybiera szerokość memaddr: 8 lub 16 bitów.

Prawidłowe tylko w trybie kontrolera.

recv(recv: int | bytearray, addr: int = 0x00, *, timeout: int = 5000) bytes

Odbiera dane z magistrali:

  • recv może być liczbą całkowitą, czyli liczbą bajtów do odebrania, lub modyfikowalnym buforem, który zostanie wypełniony odebranymi bajtami

  • addr to adres, z którego odbierane są dane (wymagany tylko w trybie kontrolera)

  • timeout to limit czasu w milisekundach oczekiwania na odbiór

Wartość zwracana: jeśli recv jest liczbą całkowitą, to nowy bufor z odebranymi bajtami, w przeciwnym razie ten sam bufor, który został przekazany do recv.

send(send: int | bytes | bytearray, addr: int = 0x00, *, timeout: int = 5000) None

Wysyła dane na magistralę:

  • send to dane do wysłania (liczba całkowita do wysłania lub obiekt buforu).

  • addr to adres, na który dane są wysyłane (wymagany tylko w trybie kontrolera).

  • timeout to limit czasu w milisekundach oczekiwania na wysłanie.

scan() List[int]

Skanuje wszystkie adresy I2C od 0x01 do 0x7f i zwraca listę tych, które odpowiadają. Prawidłowe tylko w trybie kontrolera.

Stałe

CONTROLLER: int

Inicjalizuje magistralę jako urządzenie nadrzędne (kontroler) – steruje ono linią SCL i inicjuje transakcje.

PERIPHERAL: int

Inicjalizuje magistralę jako urządzenie podrzędne (peryferyjne), które nasłuchuje pod adresem addr ustawionym w init() i odpowiada na transakcje rozpoczęte przez kontroler na tej samej magistrali.