класс I2C – двухпроводной последовательный протокол

I2C – это двухпроводной протокол для связи между устройствами. На физическом уровне он состоит из двух линий, SCL (тактовая) и SDA (данные). OpenMV Cam не обеспечивает встроенных подтягивающих резисторов ни на одной из линий – для работы шины требуются внешние подтягивающие резисторы как на SCL, так и на SDA.

Объекты I2C привязаны к определённой шине и могут быть инициализированы во время создания или позже через init().

Пример:

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

Вывод объекта I2C показывает его конфигурацию.

Основные методы – send() и 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

Чтобы принимать на месте, сначала создайте bytearray:

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

Вы можете указать тайм-аут (в мс):

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

Контроллер должен указать адрес получателя:

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

Контроллер также имеет следующие методы:

# 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)

Конструкторы

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

Создаёт объект I2C на заданной шине bus (целочисленный индекс периферийного устройства, например 2 для I2C2). Без дополнительных параметров объект создаётся, но не инициализируется (он сохраняет предыдущие настройки шины, если таковые имеются); если переданы дополнительные аргументы, шина инициализируется. Доступные параметры смотрите в init().

I2C(2) подключён к одним и тем же выводам разъёма на каждой OpenMV Cam, предоставляющей pyb.I2C (M4 / M7 / H7 / H7 Plus / Pure Thermal):

Сигнал

Вывод разъёма

Примечания

SCL

P4

SDA

P5

I2C(4) дополнительно доступен на OpenMV Cam M7, H7, H7 Plus и Pure Thermal с SCL на выводе разъёма P7 и SDA на выводе разъёма P8.

OpenMV Cam N6 не предоставляет pyb.I2C; используйте machine.I2C вместо него.

Методы

deinit() None

Выключает шину I2C.

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

Инициализирует шину I2C с заданными параметрами:

  • mode должен быть либо I2C.CONTROLLER, либо I2C.PERIPHERAL.

  • addr – это 7-битный адрес (имеет смысл только для периферийного устройства).

  • baudrate – это тактовая частота SCL (имеет смысл только для контроллера).

  • gencall – поддерживать ли режим общего вызова (general-call).

  • dma – разрешать ли использование DMA для передач I2C (учтите, что передачи DMA имеют более точную синхронизацию, но в настоящее время неправильно обрабатывают ошибки шины).

Фактическая тактовая частота может быть ниже запрошенной. Это зависит от аппаратной платформы. Фактическую частоту можно определить, выведя объект I2C.

is_ready(addr: int) bool

Проверяет, отвечает ли устройство I2C по заданному адресу. Допустимо только в режиме контроллера.

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

Читает из памяти устройства I2C:

  • data может быть целым числом (количеством байтов для чтения) или буфером для чтения в него

  • addr – это адрес устройства I2C

  • memaddr – это ячейка памяти внутри устройства I2C

  • timeout – это тайм-аут в миллисекундах ожидания чтения

  • addr_size выбирает ширину memaddr: 8 или 16 бит

Возвращает прочитанные данные. Допустимо только в режиме контроллера.

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

Записывает в память устройства I2C:

  • data может быть целым числом или буфером для записи из него.

  • addr – это адрес устройства I2C.

  • memaddr – это ячейка памяти внутри устройства I2C.

  • timeout – это тайм-аут в миллисекундах ожидания записи.

  • addr_size выбирает ширину memaddr: 8 или 16 бит.

Допустимо только в режиме контроллера.

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

Принимает данные на шине:

  • recv может быть целым числом, которое является количеством байтов для приёма, или изменяемым буфером, который будет заполнен принятыми байтами

  • addr – это адрес, с которого нужно принимать (требуется только в режиме контроллера)

  • timeout – это тайм-аут в миллисекундах ожидания приёма

Возвращаемое значение: если recv – целое число, то новый буфер из принятых байтов, в противном случае тот же буфер, который был передан в recv.

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

Отправляет данные на шине:

  • send – это данные для отправки (целое число для отправки или объект-буфер).

  • addr – это адрес, на который нужно отправить (требуется только в режиме контроллера).

  • timeout – это тайм-аут в миллисекундах ожидания отправки.

scan() List[int]

Сканирует все адреса I2C от 0x01 до 0x7f и возвращает список тех, что отвечают. Допустимо только в режиме контроллера.

Константы

CONTROLLER: int

Инициализирует шину как ведущее устройство (контроллер) – оно управляет SCL и инициирует транзакции.

PERIPHERAL: int

Инициализирует шину как ведомое устройство (периферийное), которое слушает по адресу addr, заданному в init(), и отвечает на транзакции, начатые контроллером на той же шине.