class I2C – двухпроводной последовательный протокол#
I2C – это двухпроводной протокол для обмена данными между устройствами. На физическом уровне он состоит из 2 проводов: SCL и SDA – линии тактирования и данных соответственно.
Объекты I2C создаются привязанными к конкретной шине. Они могут быть инициализированы при создании или позже.
Вывод объекта I2C на печать даёт информацию о его конфигурации.
Существуют как аппаратная, так и программная реализации I2C через классы I2C и SoftI2C. Аппаратный I2C использует встроенную аппаратную поддержку системы для выполнения чтения/записи и обычно эффективен и быстр, но может иметь ограничения на то, какие выводы можно использовать. Программный I2C реализован через bit-banging и может использоваться на любом выводе, но не так эффективен. Эти классы имеют одинаковый набор методов и отличаются главным образом способом создания.
Примечание
Для работы шины I2C требуются подтягивающие резисторы как на SDA, так и на SCL. Обычно это резисторы номиналом от 1 до 10 кОм, подключённые от каждой линии SDA/SCL к Vcc. Без них поведение не определено и может варьироваться от блокировки и неожиданного сброса по сторожевому таймеру до просто неверных значений. Часто такая подтягивающая схема уже встроена в плату MCU или в платы расширения с датчиками, но это не правило. Поэтому при возникновении проблем, пожалуйста, проверьте это. См. также это отличное руководство от Adafruit о подключении I2C.
Пример использования:
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
Конструкторы#
- class machine.I2C(id: int, *, scl: Pin | None = None, sda: Pin | None = None, freq: int = 400000, timeout: int = 50000)#
Создаёт и возвращает новый объект I2C, используя следующие параметры:
id идентифицирует конкретное периферийное устройство I2C. Допустимые значения зависят от конкретного порта/платы
scl должен быть объектом вывода, указывающим вывод для использования в качестве SCL.
sda должен быть объектом вывода, указывающим вывод для использования в качестве SDA.
freq должен быть целым числом, задающим максимальную частоту для SCL.
timeout – это максимальное время в микросекундах, отводимое на транзакции I2C. Этот параметр недоступен на некоторых портах.
Обратите внимание, что некоторые порты/платы имеют значения scl и sda по умолчанию, которые можно изменить в этом конструкторе. У других значения scl и sda фиксированы и не могут быть изменены.
Общие методы#
- init(scl: Pin, sda: Pin, *, freq: int = 400000) None#
Инициализирует шину I2C с заданными аргументами:
scl – это объект вывода для линии SCL
sda – это объект вывода для линии SDA
freq – это тактовая частота SCL
В случае аппаратного I2C фактическая тактовая частота может быть ниже запрошенной. Это зависит от аппаратной платформы. Фактическую частоту можно определить, выведя объект I2C на печать.
Примитивные операции I2C#
Следующие методы реализуют примитивные операции контроллера шины I2C и могут комбинироваться для составления любой транзакции I2C. Они предоставляются на случай, если вам нужен больший контроль над шиной, в противном случае можно использовать стандартные методы (см. ниже).
Эти методы доступны только в классе
SoftI2C.- start() None#
Генерирует условие START на шине (SDA переходит на низкий уровень, пока SCL находится на высоком уровне).
- stop() None#
Генерирует условие STOP на шине (SDA переходит на высокий уровень, пока SCL находится на высоком уровне).
- readinto(buf: bytearray, nack: bool = True, /) None#
Читает байты с шины и сохраняет их в buf. Количество прочитанных байтов равно длине buf. После приёма всех байтов, кроме последнего, на шину отправляется ACK. После приёма последнего байта, если nack истинно, отправляется NACK, иначе отправляется ACK (и в этом случае периферийное устройство предполагает, что в последующем вызове будут прочитаны ещё байты).
Стандартные операции шины#
Следующие методы реализуют стандартные операции чтения и записи контроллера I2C, нацеленные на заданное периферийное устройство.
- readfrom(addr: int, nbytes: int, stop: bool = True, /) bytes#
Читает nbytes из периферийного устройства, заданного addr. Если stop истинно, в конце передачи генерируется условие STOP. Возвращает объект
bytesс прочитанными данными.
- readfrom_into(addr: int, buf: bytearray, stop: bool = True, /) None#
Читает в buf из периферийного устройства, заданного addr. Количество прочитанных байтов будет равно длине buf. Если stop истинно, в конце передачи генерируется условие STOP.
Метод возвращает
None.
- writeto(addr: int, buf: bytes, stop: bool = True, /) int#
Записывает байты из buf в периферийное устройство, заданное addr. Если после записи байта из buf получен NACK, то оставшиеся байты не отправляются. Если stop истинно, в конце передачи генерируется условие STOP, даже если получен NACK. Функция возвращает количество полученных ACK.
- writevto(addr: int, vector: tuple | list, stop: bool = True, /) int#
Записывает байты, содержащиеся в vector, в периферийное устройство, заданное addr. vector должен быть кортежем или списком объектов с буферным протоколом. addr отправляется один раз, после чего байты из каждого объекта в vector записываются последовательно. Объекты в vector могут иметь нулевую длину, и в этом случае они не вносят вклад в вывод.
Если после записи байта из одного из объектов в vector получен NACK, то оставшиеся байты и любые оставшиеся объекты не отправляются. Если stop истинно, в конце передачи генерируется условие STOP, даже если получен NACK. Функция возвращает количество полученных ACK.
Операции с памятью#
Некоторые устройства I2C работают как устройство памяти (или набор регистров), из которого можно читать и в которое можно записывать. В этом случае с транзакцией I2C связаны два адреса: адрес периферийного устройства и адрес памяти. Следующие методы являются удобными функциями для обмена данными с такими устройствами.
- readfrom_mem(addr: int, memaddr: int, nbytes: int, *, addrsize: int = 8) bytes#
Читает nbytes из периферийного устройства, заданного addr, начиная с адреса памяти, заданного memaddr. Аргумент addrsize задаёт размер адреса в битах. Возвращает объект
bytesс прочитанными данными.
- readfrom_mem_into(addr: int, memaddr: int, buf: bytearray, *, addrsize: int = 8) None#
Читает в buf из периферийного устройства, заданного addr, начиная с адреса памяти, заданного memaddr. Количество прочитанных байтов равно длине buf. Аргумент addrsize задаёт размер адреса в битах.
Метод возвращает
None.
class SoftI2C – программно-эмулируемая шина I2C#
Класс SoftI2C реализует I2C посредством bit-banging произвольных выводов GPIO. Он предоставляет тот же набор методов, что и I2C, плюс низкоуровневые примитивные операции шины (start(), stop(), readinto(), write()) для вызывающего кода, которому нужно собрать нестандартные транзакции. Используйте его, когда нужные вам выводы не подключены к аппаратному блоку I2C, когда вам нужно больше шин, чем предоставляет аппаратура, или для общения с устройствами, требующими необычных последовательностей (дополнительные такты, повторные старты после записи и т. д.).
Конструкторы#
- class machine.SoftI2C(scl: Pin, sda: Pin, *, freq: int = 400000, timeout: int = 50000)#
Создаёт программную шину I2C, управляемую
scl/sda.freq– это целевая тактовая частота SCL в Гц (фактическая частота обычно ниже из-за накладных расходов цикла bit-banging).timeout– это максимальное время в микросекундах ожидания растягивания тактового сигнала (когда SCL удерживается на низком уровне другим устройством на шине); по истечении вызываетсяOSError(ETIMEDOUT).Общие методы#
Примитивные операции I2C#
Следующие методы реализуют примитивные операции контроллера шины I2C и могут комбинироваться для составления любой транзакции I2C. Они доступны только в SoftI2C – аппаратный класс
I2Cих не предоставляет.- start() None#
Генерирует условие START на шине (SDA переходит на низкий уровень, пока SCL находится на высоком уровне).
- stop() None#
Генерирует условие STOP на шине (SDA переходит на высокий уровень, пока SCL находится на высоком уровне).
- readinto(buf: bytearray, nack: bool = True, /) None#
Читает байты с шины в
buf. Читаетсяlen(buf)байтов; после каждого байта, кроме последнего, отправляется ACK. После последнего байтаnack=True(по умолчанию) отправляет NACK для завершения передачи;nack=Falseотправляет ACK, чтобы устройство оставалось выбранным для последующегоreadinto().
Стандартные операции шины#
Следующие методы реализуют стандартные операции чтения и записи контроллера I2C, нацеленные на заданное периферийное устройство.
- readfrom(addr: int, nbytes: int, stop: bool = True, /) bytes#
Читает
nbytesиз устройства с 7-битным адресомaddr. Еслиstopистинно, в конце передачи генерируется условие STOP.
- readfrom_into(addr: int, buf: bytearray, stop: bool = True, /) None#
Читает
len(buf)байтов из устройства с адресомaddrвbuf. Еслиstopистинно, в конце передачи генерируется условие STOP.
Операции с памятью#
Некоторые устройства I2C работают как устройство памяти (или набор регистров), из которого можно читать и в которое можно записывать. В этом случае с транзакцией I2C связаны два адреса: адрес периферийного устройства и адрес памяти. Следующие методы являются удобными вспомогательными средствами для общения с такими устройствами.
- readfrom_mem(addr: int, memaddr: int, nbytes: int, *, addrsize: int = 8) bytes#
Читает
nbytesиз устройства с адресомaddr, начиная с регистраmemaddr.addrsize– это ширина адреса регистра в битах (обычно8или16).