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