В данной статье рассмотрим как использовать UART в ESP32 на примере платы ESP32 WROOM. разберем минимальный проект по передаче данных с компьютера на ESP32.
ESP32 uart0
Обратившись к описанию платы мы видим, что ESP32 имеет два порта UART: UART0 и UART1.
Модуль UART0 выведен на ножки 1 и 3, а модуль UART1 выведен на ножки 16 и 17. Данная информация нам понадобиться для разработки программы.
В нашем примере мы будем использовать UART0.
Подключение uart в ESP32
Подключение к модулю производится так же как и с другими микроконтроллерами. Ножку Tx необходимо соединить с ножкой Rx устройства. Ножку Rx с ножкой Tx устройства. Подробнее подключение расписано на ниже приведенной схеме.

Пример минимальной программы ESP32
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include <inttypes.h>
#include "driver/uart.h"
#include "string.h"
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "main.h"
#include "time.h"
#include "sys/time.h"
#include "uartWork.h"
#define TXD_PIN (GPIO_NUM_1)
#define RXD_PIN (GPIO_NUM_3)
static const int RX_BUF_SIZE = 128;
esp_uart_t usartWorks;
//Очищаем буферы от данных
void FreeBuf(uint8_t* buff, uint32_t sizeb)
{
for(int i = 0; i < sizeb; i++)
{
buff[i] = 0;
}
}
void init_UART(void) {
const uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_APB,
};
uart_driver_install(UART_NUM_0, RX_BUF_SIZE * 2, 0, 0, NULL, 0);
uart_param_config(UART_NUM_0, &uart_config);
uart_set_pin(UART_NUM_0, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
}
int sendData(const char* data)
{
int txBytes = 0;
const int len = strlen(data);
txBytes = uart_write_bytes(UART_NUM_0, data, len);
return txBytes;
}
static void rx_task(void *arg)
{
uint8_t* data = (uint8_t*) malloc(RX_BUFER_SIZE+1);
while (1) {
const int rxBytes = uart_read_bytes(UART_NUM_0, data, RX_BUFER_SIZE, 1000 / portTICK_PERIOD_MS);
if (rxBytes > 0)
{
data[rxBytes] = 0;
for (int i=0;i<rxBytes;i++)
{
usartWorks.dataRX[i] = data[i];
}
usartWorks.dataRxByte = rxBytes;
//printf("Get date: %s\n", usartWorks.dataRX);
strcat((char *)usartWorks.dataTX, (char*) "Send date: \0");
strcat((char *)usartWorks.dataTX, (char*) usartWorks.dataRX);
strcat((char *)usartWorks.dataTX, END_MESSEGE);
sendData((char*)usartWorks.dataTX);
FreeBuf(usartWorks.dataTX,TX_BUFER_SIZE);
FreeBuf(usartWorks.dataRX,RX_BUFER_SIZE);
}
}
free(data);
vTaskDelay(10 / portTICK_PERIOD_MS);
}
void app_main(void)
{
esp_err_t ret;
/* Initialize NVS. */
ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
init_UART();
xTaskCreate(rx_task, "uart_rx_task", 1024*2, NULL, tskIDLE_PRIORITY, NULL);
}
#include "driver/uart.h"
#include "esp_types.h"
#include "esp_event.h"
#include "esp_err.h"
#include "driver/uart.h"
#define RX_BUFER_SIZE 256
#define TX_BUFER_SIZE 128
#define END_MESSEGE "\r\n"
typedef struct
{
uint8_t dataRX[RX_BUFER_SIZE];
uint8_t dataTX[TX_BUFER_SIZE];
uint8_t dataRxByte;
} esp_uart_t;
Для удобства работы была создана структура esp_uart_t, содержащая 2 буфера. В них мы будем записывать и считывать данные.
Перед использованием UART, его необходимо настроить. Для этого используем функцию initUART. В ней мы настраиваем скорость передачи, бит четности и т.д.
После настройки мы можем использовать прием и передачу через UART.
В примере мы используем операционную систему freeRTOS, по этому прием данных мы будем осуществлять в созданной задаче rx_task. Созданная задача реализует следующую задачу.
с Пк по uart приходят данные, мы их принимаем, затем отправляем обратно, добавив к сообщению Send date.
Что бы запустить задачу, необходимо вызвать функцию xTaskCreate и передать ей одним из аргументов название задачи.



