DocsTech
/
NONEDISPLAY
/

~ cd esp32 i2c: настройка кода под master и slave

ESP32, с его мощными возможностями и высокой эффективностью, предоставляет разработчикам уникальные возможности для работы с различными периферийными устройствами. Одним из ключевых интерфейсов, который часто используется для связи с различными датчиками и устройствами, является I2C. В данной статье мы рассмотрим, как эффективно использовать интерфейс I2C на ESP32, а также приведем примеры объявления интерфейсов с комментариями, чтобы помочь разработчикам освоить эту технологию.

Оптимальное использование интерфейса I2C на ESP32

  1. Выбор пинов: При использовании I2C на ESP32 необходимо выбрать соответствующие пины для подключения SDA и SCL. Обычно для этого используются пины GPIO21 (SDA) и GPIO22 (SCL).
  2. Инициализация интерфейса: Для работы с I2C на ESP32 необходимо инициализировать интерфейс. Для этого используется функция i2c_param_config для конфигурации параметров I2C и i2c_driver_install для установки драйвера.
  3. Настройка скорости передачи: ESP32 поддерживает разные скорости передачи данных по интерфейсу I2C. При инициализации интерфейса можно указать нужную скорость с помощью параметра i2c_config_t.
  4. Обработка ошибок: Важно предусмотреть обработку возможных ошибок при работе с интерфейсом I2C, таких как потеря соединения с устройством или неверная конфигурация.

Пример объявления интерфейсов I2C на ESP32

Инициализирует интерфейс I2C, отправляет строку «hello world» и читает ответ от ведомого устройства, затем выводит полученное сообщение на консоль. Пример настройки мастера на C/C++:
...
Копировать
#include <stdio.h>
#include <string.h>
#include "driver/i2c.h"

#define I2C_MASTER_SCL_IO    22    /*!< GPIO номер для SCL */
#define I2C_MASTER_SDA_IO    21    /*!< GPIO номер для SDA */
#define I2C_MASTER_NUM       I2C_NUM_0 /*!< Номер I2C порта */
#define I2C_MASTER_FREQ_HZ   100000     /*!< Скорость передачи данных I2C */
#define I2C_MASTER_TX_BUF_DISABLE   0 /*!< Отключить буфер передачи */
#define I2C_MASTER_RX_BUF_DISABLE   0 /*!< Отключить буфер приема */
#define I2C_SLAVE_ADDR      0x28     /*!< Адрес I2C ведомого устройства */

void i2c_master_init() {
    i2c_config_t conf;
    conf.mode = I2C_MODE_MASTER; // объявление мастера
    conf.sda_io_num = I2C_MASTER_SDA_IO; // объявление порты SDA
    conf.scl_io_num = I2C_MASTER_SCL_IO; // объявление порты SCL
    conf.sda_pullup_en = GPIO_PULLUP_ENABLE; // вкл подтягивающий резистор к порту SDA
    conf.scl_pullup_en = GPIO_PULLUP_ENABLE; // вкл подтягивающий резистор к порту SCL
    conf.master.clk_speed = I2C_MASTER_FREQ_HZ; // частота передачи
    i2c_param_config(I2C_MASTER_NUM, &conf);
    i2c_driver_install(I2C_MASTER_NUM, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
}

// функция записи
void i2c_master_write_slave(uint8_t* data, size_t data_len) {
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (I2C_SLAVE_ADDR << 1) | I2C_MASTER_WRITE, true);
    i2c_master_write(cmd, data, data_len, true);
    i2c_master_stop(cmd);
    i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_PERIOD_MS);
    i2c_cmd_link_delete(cmd);
}

// функция чтения
void i2c_master_read_slave(uint8_t* data, size_t data_len) {
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (I2C_SLAVE_ADDR << 1) | I2C_MASTER_READ, true);
    i2c_master_read(cmd, data, data_len, I2C_MASTER_LAST_NACK);
    i2c_master_stop(cmd);
    i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_PERIOD_MS);
    i2c_cmd_link_delete(cmd);
}

void app_main() {
    i2c_master_init();

    // Отправка строки "hello world"
    uint8_t data_to_send[] = "hello world";
    i2c_master_write_slave(data_to_send, strlen((char*)data_to_send));

    // Задержка для ожидания ответа от ведомого устройства
    vTaskDelay(1000 / portTICK_PERIOD_MS);

    // Чтение ответа от ведомого устройства
    uint8_t data_received[128];
    memset(data_received, 0, sizeof(data_received));
    i2c_master_read_slave(data_received, sizeof(data_received) - 1);

    // Печать полученного сообщения
    printf("Received message: %s\n", data_received);
}
Пример настройки устройства под ведомого на C/C++:
...
Копировать
#include <stdio.h>
#include "driver/i2c.h"

#define I2C_SLAVE_SCL_IO    22    /*!< GPIO номер для SCL */
#define I2C_SLAVE_SDA_IO    21    /*!< GPIO номер для SDA */
#define I2C_SLAVE_NUM       I2C_NUM_0 /*!< Номер I2C порта */
#define I2C_SLAVE_FREQ_HZ   100000     /*!< Скорость передачи данных I2C */
#define CONFIG_ESP_SLAVE_ADDR 30     /*!< Адрес ведомого устройства */

void i2c_init() {
    i2c_config_t conf;
    conf.mode = I2C_MODE_SLAVE; // объявление мастера
    conf.sda_io_num = I2C_SLAVE_SDA_IO; // объявление линии SDA
    conf.scl_io_num = I2C_SLAVE_SCL_IO; // объявление линии SCL
    conf.sda_pullup_en = GPIO_PULLUP_ENABLE; // подтягивание резисторов к линии SDA
    conf.scl_pullup_en = GPIO_PULLUP_ENABLE; // подтягивание резисторов к линии SCL
    conf.master.clk_speed = I2C_SLAVE_FREQ_HZ;  // скорость передачи
    conf.clk_flags = 0;
    conf.slave.slave_addr = CONFIG_ESP_SLAVE_ADDR;
    conf.slave.addr_10bit_en = 0;
    i2c_param_config(I2C_SLAVE_NUM, &conf);
    i2c_driver_install(I2C_SLAVE_NUM, conf.mode, 0, 0, 0);
}

void app_main() {
    i2c_init();
    // Дальнейший код для работы с устройствами по I2C
}

Заключение

Использование интерфейса I2C на ESP32 позволяет разработчикам эффективно взаимодействовать с различными периферийными устройствами. Правильная инициализация интерфейса, выбор пинов и обработка ошибок являются ключевыми моментами при использовании этой технологии. Приведенный пример объявления интерфейсов с комментариями поможет разработчикам быстро освоить работу с I2C на ESP32 и использовать его в своих проектах.

Главная
Курсы
Вебинары
Анализ рынка вакансий в сфере RTL-дизайна в России: тренды, спрос и перспективы
LinuxCNC: Преимущества и применение в станкостроении и автоматизации
Алгоритм Хаффмана: Теория, методология и практическая реализация для эффективного сжатия данных
Chisel vs. SystemVerilog: Новый взгляд на проектирование цифровых схем
Подключение датчика ZMPT101B к Arduino: схема, настройка и пример кода
Подключение MAX6675 к Arduino: схема, библиотеки и примеры кода
Подключение и настройка MPU6050 к Arduino: схема, библиотеки и скетч
Подключение VL53L0X к Arduino: полное руководство по лазерному датчику расстояния
Подключение компас HMC5883L к Arduino: схема, библиотеки и пример кода
Подключение ACS712 к Arduino: схема, библиотеки и скетчи
Подключение ADXL345 к Arduino: схема, библиотеки и код
Подключение датчика INA219 к Arduino: схема, библиотеки и примеры кода
HC-SR04 и Arduino: схема подключения, библиотеки и скетч
Assertion-Based Verification(ABV): основные понятия, принцип работы и примеры
Подключение HX711 к Arduino: схема, библиотеки и код
Подключение DHT22 к Arduino: схема, код и необходимые библиотеки
Как подключить RCWL-0516 к Arduino: схема, библиотеки и скетч
Универсальная Методология Верификации (UVM): Описание, Особенности и Пример Использования
DS18B20: Подключение к Arduino, Библиотеки и Скетч
Методологии верификации HDL-кода: Основы, Преимущества и Популярные Подходы
Роль ПЛИС в Алготрейдинге и Высокочастотной Торговле
Lint, CDC, RDC, LEC, Power Analyzer, STA и DFT для HDL
Пиратство плохо! Мне так сказали…
Применение Icarus Verilog для тестирования с входными данными
Ключевые параметры для выбора цифроаналогового преобразователя (ЦАП)
Все о КНФ и ДНФ: Понятие, Примеры и Применение
Импликация: Что Это, Таблица Истинности и Применение в Информатике
Стрелка Пирса: Что Это за Логическая Операция и Таблица Истинности
Штрих Шеффера: Полное Руководство
STM32F103 с использованием HAL и I2C: Подробная конфигурация и пример кода
Подключение DHT11 к ESP32: Схема, Библиотеки и Пример Кода
ESP8266 I2C: настройка для master и slave
Подключение DHT11 к Arduino и Вывод на LCD 1602 I2C: Схема и Скетч
Подключение DHT11 к Arduino: Схема, Библиотеки и Скетч
ESP32 I2C: Настройка кода под master и slave
TM1637 Подключение к Arduino: Полное Руководство
Подключение часов DS3231 к Arduino и LCD 1602 I2C
Arduino: Часы Реального Времени DS1302 на LCD 1602 I2C
ESP32 SPI: Объявление SPI на ESP32 с Примером Кода
ESP8266 SPI: полная инструкция SPI на ESP8266
Протокол SPI: Регистровая Логика, Передача Данных и Режимы
Демультиплексор: принцип работы, схема и основы
Счетчики с синхронным и асинхронным сбросом на Verilog
Знаковость signed в Verilog: примеры, синтаксис, оптимизация
Директива Define в Verilog: Синтаксис, Примеры и Применение
Таблицы истинности триггеров: JK, RS, D и T
Fork и begin в Verilog: обзор и различия
Posedge и Negedge в Verilog: Синтаксис и Функциональность
Verilog always: Синтаксис, Примеры и Применение
Wire в Verilog: Основы использования, синтаксис и примеры кода
Блокирующие и неблокирующие присваивания в Verilog
Verilog Assign: что делает этот оператор?
Verilog Parameter: Ключевой Инструмент Оптимизации
Многомерные массивы в Verilog
Case Verilog
Дешифратор. Принцип работы и Примеры
Модули в Verilog
Описание FIFO. Примеры на Verilog и С++
Закрыть