Рассмотрим как настроить прием и передачу данных через I2C в ESP32. Про устройство I2C поговорим в следующих статьях. В этой же статье рассмотрим, как используя IDF-IDE записать и считать данные с устройства по I2C. В качестве ESP32 чипа, будем использовать ESP32 S3 Mini.
Коротко о I2C в ESP32
Шина I2C представляет собой двухпроводную шину к которой подключаются различные устройства:
Каждое устройство имеет собственный адрес, по которому главное устройство обменивается сообщениями с подчиненными. В ESP32 разработаны 2 библиотеки i2c_master.h и i2c_slave.h. В старых версиях драйвера, используется библиотека i2c.h. В ESP32 рекомендуют использовать первые две библиотеки. Однако у меня их не нашлось, по этому я использовал старую версию. Что бы подключить данную библиотеку необходимо добавить в начало программы следующую строчку:
#include “driver/i2c.h”
Адрес I2C устройства бывает 7-битный или 10-битный. Микроконтроллером ESP32 поддерживается два режима работы:
- Cтандартный режим (Slow mode). Скорость передачи данных 100 кГц;
- Быстрый режим (Fast mode). Скорость передачи данных 400 кГц.
ВНИМАНИЕ!
На частоту SCL влияют как подтягивающий резистор, так и емкость провода. Поэтому пользователям настоятельно рекомендуется выбирать подходящие подтягивающие резисторы, чтобы обеспечить точность частоты. Рекомендуемое значение подтягивающих резисторов обычно находится в диапазоне от 1 до 10 кОм.
Имейте в виду, что чем выше частота, тем меньше должен быть подтягивающий резистор (но не менее 1 КОм). Действительно, резисторы большой емкости будут снижать ток, что приведет к увеличению времени переключения тактовых импульсов и снижению частоты. Обычно мы рекомендуем диапазон от 2 КОм до 5 КОм, но пользователям также может потребоваться внести некоторые корректировки в зависимости от их текущих требований к потреблению.
Pinout I2C в ESP32
В наших экспериментах мы будем использовать S3 mini board. Из документации на семейство микроконтроллеров ESP32 S3 мы видим, что интерфейс I2C располагается на выводах GPIO4 (SCL) и GPIO5 (SDA). Если брать не отладочную плату а чистый контроллер, то I2C можно использовать на любом выводе.
I2C master в ESP32
Для настройки I2C в ESP32 на работу в режиме мастера (ведущего устройства), необходимо подключить библиотеку i2c_master.h.
Следующим шагом будет заполнение структуры i2c_config_t. С ее помощью настраивается драйвер I2C. Рассмотрим ее основные поля:
- mode – режим мастера I2C_MODE_MASTER или режим подчиненного устройства I2C_MODE_SLAVE;
- sda_io_num – указываем на каком пине контакт SDA;
- scl_io_num – здесь настраиваем контакт SCL;
- sda_pullup_en – подтяжка SDA;
- scl_pullup_en – подтяжка SCL;
- master.clk_speed – скорость обмена.
Заполнив структуру i2c_config_t, необходимо вызвать функцию
esp_err_t i2c_param_config(i2c_port_t i2c_num, const i2c_config_t *i2c_conf), где
i2c_num – номер используемого порта i2c. Принимает значения от 0 до I2C_NUM_MAX-1.
i2c_conf – переменная структуры i2c_config_t.
После этого драйвер i2C необходимо инсталлировать вызвав функцию i2c_driver_install:
i2c_driver_install(i2c_port_t i2c_num, i2c_mode_t mode, size_t slv_rx_buf_len, size_t slv_tx_buf_len, int intr_alloc_flags), где
i2c_num – номер используемого порта i2c. Принимает значения от 0 до I2C_NUM_MAX-1;
mode – режим работы устройства, мастер или слэйв;
slv_rx_buf_len, slv_tx_buf_len – длинна буферов, если используется режим слэйв ;
intr_alloc_flags – флаг использования прерывания.
Ниже приведен пример инициализации мастера I2C для обмена данными с устройством по шине I2C:
#define I2C_MASTER_NUM 0
#define I2C_MASTER_FREQ_HZ 100000
#define I2C_SCL GPIO_NUM_4
#define I2C_SDA GPIO_NUM_5
#define I2C_MASTER_TX_BUF_DISABLE 0
#define I2C_MASTER_RX_BUF_DISABLE 0
static esp_err_t i2c_master_init(void)
{
int i2c_master_port = I2C_MASTER_NUM;
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C_SDA,
.scl_io_num = I2C_SCL,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = I2C_MASTER_FREQ_HZ,
};
i2c_param_config(i2c_master_port, &conf);
return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
}
I2C master write
Для записи данных в подчиненное устройство по I2C, необходимо использовать функцию i2c_master_write_to_device.
i2c_master_write_to_device(i2c_port_t i2c_num, uint8_t device_address, const uint8_t *write_buffer, size_t write_size, TickType_t ticks_to_wait)
- i2c_num – номер I2C порта;
- device_address – 7 битный адрес устройства слэйв;
- write_buffer – буфер с данными на запись;
- write_size – размер записываемых данных;
- ticks_to_wait – таймаут ожидания завершения операции;
I2C master read
Для чтения данных от устройства слэйв используйте функцию: i2c_master_write_read_device
i2c_master_write_read_device(i2c_port_t i2c_num, uint8_t device_address, const uint8_t *write_buffer, size_t write_size, uint8_t *read_buffer, size_t read_size, TickType_t ticks_to_wait)
- i2c_num – номер I2C порта;
- device_address – 7 битный адрес устройства слэйв;
- write_buffer – буфер с данными на запись;
- write_size – размер записываемых данных;
- read_buffer – буфер для принятых данных от слэйва;
- read_size – количество байт, которые ходим принять;
- ticks_to_wait – таймаут ожидания завершения операции;
***
Это не единственный способ для работы с шиной I2C в ESP32. Поэтому в статье будут еще описаны другие функции для работы с I2C.




