I2C
Модуль I2C определяет числовую константу для каждого доступного I2C-устройства. Например, на ESP32 I2C0 определен константой i2c.I2C0. Пожалуйста, обратитесь к документации вашей платформы или платы, чтобы узнать, какие I2C-устройства доступны. Если вы обращаетесь к несуществующему I2C, возвращается значение nil.
Модуль I2C может работать в режиме мастера или ведомого, каждый из которых идентифицируется константами i2c.MASTER и i2c.SLAVE. На данный момент разрешен только i2c.MASTER.
I2C (Inter-Integrated Circuit) — это многомастерная, многоведомая, пакетно-переключаемая, однопроводная, последовательная компьютерная шина, изобретенная фирмой Philips Semiconductor (теперь NXP Semiconductors). Обычно она используется для подключения периферийных интегральных схем с низкой скоростью к процессорам и микроконтроллерам для общения на короткие расстояния внутри платы.
I2C использует только две двунаправленные линии с открытым стоком: линию передачи данных (SDA) и линию тактового сигнала (SCL), подтянутые резисторами.
I2C имеет 7-битное или 10-битное (в зависимости от используемого устройства) адресное пространство. Общие скорости шины I2C — стандартный режим 100 кбит/с и низкоскоростной режим 10 кбит/с, но также допускаются произвольно низкие частоты тактового сигнала. Недавние версии I2C могут поддерживать больше узлов и работать на более высоких скоростях (400 кбит/с в режиме Fast, 1 Мбит/с в режиме Fast mode plus или Fm+ и 3,4 Мбит/с в режиме High Speed).
Следует отметить, что указанные скорости передачи данных применяются для транзакций между мастером и ведомым без учета растяжения тактового сигнала или других аппаратных накладных расходов. К протокольным накладным расходам относятся адрес ведомого устройства и, возможно, адрес регистра внутри ведомого устройства, а также биты подтверждения/не подтверждения для каждого байта. Таким образом, фактическая скорость передачи данных пользователя ниже, чем эти максимальные битовые скорости.
Максимальное количество узлов ограничено адресным пространством и общей емкостью шины 400 пФ, что ограничивает практические расстояния коммуникации до нескольких метров.
instance = i2c.attach(id, mode, [speed])
Подключить устройство I2C.
Аргументы:
- id: идентификатор устройства I2C. Используйте i2c.I2Cx, определенный для этой цели.
- mode: может быть либо i2c.MASTER, либо i2c.SLAVE. На данный момент поддерживается только i2c.MASTER.
- speed (необязательно): скорость шины I2C, выраженная в герцах. Этот аргумент необязателен, и если он не предоставлен, применяется стандартная скорость 40000 (400 килогерц).
Возвращает: экземпляр устройства i2c или исключение. Этот экземпляр необходимо сохранить в переменной для дальнейших операций с ним.
instance:detach()
Отсоединить экземпляр устройства i2c от шины I2C и освободить все используемые ресурсы.
Аргументы: нет.
Возвращает: ничего или исключение.
instance:setspeed(speed)
Установить скорость шины I2C для конкретного экземпляра I2C.
Аргументы:
- speed (скорость): скорость шины I2C, выраженная в герцах.
Возвращает: ничего или исключение.
instance:start()
Начать транзакцию I2C.
Аргументы: нет
Возвращает: ничего или исключение.
instance:address(address, read)
Отправить адрес на шину I2C для чтения или записи, если экземпляр I2C настроен в режиме мастера.
Аргументы:
- address (адрес): целочисленное значение с адресом I2C для отправки.
- read (чтение): логическое значение, которое указывает, используется ли адрес для чтения или записи в шину I2C или из нее. Если true, адрес используется для чтения, если false - для записи.
Возвращает: ничего или исключение.
readed data = instance:read()
Прочитать один байт с шины I2C. Перед использованием этой функции необходимо отправить адрес I2C для чтения.
Аргументы: нет
Возвращает: прочитанные данные или исключение.
instance:write(byte0, [byte1, …, byten])
Записать один или несколько байтов на шину I2C. Перед использованием этой функции необходимо отправить адрес I2C для записи.
Аргументы:
- byte0, …., byten: байты для записи.
Возвращает: ничего или исключение.
instance:write(string)
Записать строку на шину I2C. Перед использованием этой функции необходимо отправить адрес I2C для записи.
Аргументы:
- string: строка для записи.
Возвращает: ничего или исключение.
instance:stop()
Остановить транзакцию I2C.
Аргументы: нет
Возвращает: ничего или исключение.
Пример
Этот пример демонстрирует, как общаться с устройствами I2C. В примере выполняется запись значений в EEPROM (4c256d), затем происходит чтение из EEPROM и проверка того, что значения совпадают.
-- Attach the eeprom to the i2c bus
function eeprom_attach()
eeprom = i2c.attach(i2c.I2C0, i2c.MASTER, 400000)
end
-- Once the internally-timed write cycle has started and the EEPROM
-- inputs are disabled, acknowledge polling can be initiated.
-- This involves sending a start condition followed by the device address word.
-- If this fails (timeout, or ack not received) we can't write.
function eeprom_poll(devAddress)
local done = false
while not done do
try(
function()
eeprom:start()
eeprom:address(devAddress, false)
eeprom:stop()
done = true
end
)
end
end
-- Write to eeprom (byte)
function eeprom_write(devAddress, address, value)
eeprom:start()
eeprom:address(devAddress, false)
eeprom:write(0x00, address, value)
eeprom:stop()
eeprom_poll(devAddress)
end
-- Read from eeprom (byte)
function eeprom_read(devAddress, address)
local read
eeprom:start()
eeprom:address(devAddress, false)
eeprom:write(0x00, address)
eeprom:start()
eeprom:address(devAddress, true)
read = eeprom:read()
eeprom:stop()
return read
end
-- Attach eeprom
eeprom_attach()
-- Write test bytes
for i=0,100 do
eeprom_write(0x51, i, i)
end
-- Check bytes
for i=0,100 do
if (eeprom_read(0x51, i) ~= i) then
error("Readed "..read..", expected "..i)
end
end