Рассмотрим такую тему, как gpio в ESP32. В качестве подопытной платы будем использовать ESP32-AI-C3-MINI-1 с микроконтроллером ESP-C3-M1.
Pinout ESP32 C3-AI
Диаграмма выводом выглядит следующим образом:
Из диаграммы мы видим, что у нас имеется 20 gpio ввода-вывода. Они могут быть сконфигурированы как порты ввода вывода, либо на использование альтернативных функций.
Так же у gpio в ESP32 имеется возможность настроить выходной ток на порту от 5ma до 40ma. Эти значения не точный и могут немного отличаться.
Настройка GPIO в ESP32
Для начала работы с портами ввода-вывода в ESP32, необходимо подключить такую библиотеку:
# include «driver/gpio.h»
Библиотека содержит все структуры описывающие настройки портов, а так же необходимые функции. Порты мы можем настроить следующим образом:
- Порт на вход;
- Порт на выход;
- Подтяжка к питанию (3.3 В);
- Подтяжка к земле;
- Выходной ток (5-40mA);
- Прерывания;
GPIO в ESP32 можно настроить двумя способами:
- Настройка нескольких портов за один раз. Для этого используем функцию gpio_config(const gpio_config_t* pGPIOConfig)
- Настройка порта с помощью отдельных функций предназначенных для настройки одно порта.
Если вы только начинает изучать программирование ESP32, то лучше пользоваться вторым способом. Он более детально показывает настройку портов. Будет проще читать свой код.
Режим ввода-вывода GPIO
Для начала работы с портом в режиме ввода-вывода, его необходимо перевести в этот режим.
esp_err_t gpio_reset_pin(gpio_num_t gpio_num)
gpio_num — номер порта, который хотим использовать.
Функция настраивает мультиплексор IOMUX для данного вывода на работу в режиме ввода вывода.
ВНИМАНИЕ! Так как GPIO в ESP32 используется для различных функций, то есть вероятность после включения микроконтроллера, не все GPIO будут переведены в режим ввода — вывода. По этому всегда используйте функцию gpio_reset_pin.
Конфигурация выводов
Режимы работы порта описаны в структуре gpio_mode_t:
typedef enum { GPIO_MODE_DISABLE = GPIO_MODE_DEF_DISABLE, /*!< вход и выход отключены */ GPIO_MODE_INPUT = GPIO_MODE_DEF_INPUT, /*!< GPIO настроен на вход */ GPIO_MODE_OUTPUT = GPIO_MODE_DEF_OUTPUT, /*!< GPIO настроен на выход */ GPIO_MODE_OUTPUT_OD = ((GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)), /*!< GPIO настроен на открытый сток */ GPIO_MODE_INPUT_OUTPUT_OD = ((GPIO_MODE_DEF_INPUT) | (GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)), /*!< GPIO настроен на вход и выход с открытым стоком */ GPIO_MODE_INPUT_OUTPUT = ((GPIO_MODE_DEF_INPUT) | (GPIO_MODE_DEF_OUTPUT)), /*!< GPIO настроен на вход и выход */ } gpio_mode_t;
ВНИМАНИЕ! Когда порт настроен на режим работы с открытым стоком (OD), управлять можно только низким уровнем порта. Если подать высокий уровень, порт отключится.
Для настройки порта на какой либо режим работы, используйте следующую функцию:
esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode)
gpio_num — номер настраиваемого порта,
mode — выбранный режим.
ВНИМАНИЕ! Настроить режим работы порта можно в любом месте программы.
Настройка внутренней подтяжки
Режимы внутренней подтяжки описаны в структуре gpio_pull_mode_t
typedef enum { GPIO_PULLUP_ONLY, /*!< Подтяжка к питанию 3.3 В */ GPIO_PULLDOWN_ONLY, /*!< Подтяжка к земле */ GPIO_PULLUP_PULLDOWN, /*!< Подтяжка к питанию и земле*/ GPIO_FLOATING, /*!< Подтяжка отключена */ } gpio_pull_mode_t;
Внутренняя подтяжка в ESP32 настраивается следующей функцией
esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull)
gpio_num — номер настраиваемого порта,
pull — режим внутренней подтяжки.
ВНИМАНИЕ! Внутренняя подтяжка в ESP32 составляет 45кОм.
Так же можно использовать альтернативные функции для настройки подтяжек:
esp_err_t gpio_pullup_en(gpio_num_t gpio_num) – функция включает подтяжку к питанию +3,3В esp_err_t gpio_pullup_dis(gpio_num_t gpio_num) – функция отключает подтяжку к питанию +3,3В esp_err_t gpio_pulldown_en(gpio_num_t gpio_num) – функция включает подтяжку к “земле” esp_err_t gpio_pulldown_dis(gpio_num_t gpio_num) – функция отключает подтяжку к “земле”
Настройка выходного тока порта
GPIO в ESP32 поддерживает настройку выходного тока от 5 mA до 40 mA. режимы выходного тока содержаться в структуре gpio_drive_cap_t:
typedef enum { GPIO_DRIVE_CAP_0 = 0, /*!< слабый выход окjло 5mA */ GPIO_DRIVE_CAP_1 = 1, /*!< выход примерно 10mA */ GPIO_DRIVE_CAP_2 = 2, /*!< средний выход около 20mA*/ GPIO_DRIVE_CAP_DEFAULT = 2, /*!< выход по умолчанию - средний 20 mA */ GPIO_DRIVE_CAP_3 = 3, /*!< высокий выход на 40mA */ GPIO_DRIVE_CAP_MAX, } gpio_drive_cap_t;
Настройка выходного тока осуществляется функцией:
esp_err_t gpio_set_drive_capability (gpio_num_t gpio_num , gpio_drive_cap_t strength)
gpio_num — настраиваемый порт,
strength — выходной ток порта.
Когда выходной ток не известен, то используйте функцию:
esp_err_t gpio_get_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t *strength)
Значение выходного порта будет записано в переменную strength.
Чтение-запись в порт
Для того что бы записать значение в порт, необходимо использовать функцию:
esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level)
gpio_num — номер порта для настройки,
level — — уровень порта (0-низкий, 1-высокий)
Для чтения значения порта, используется другая функция:
uint32_t gpio_get_level(gpio_num_t gpio_num)
gpio_num — номер порта для чтения.