1、ESP32串口
ESP32芯片有三个UART控制器(UART0
, UART1
和UART2
),其中UART0
(GPIO3
用于U0RXD
,GPIO1
用于U0TXD
)用作下载、调试串口,引脚不可改变;
UART1
和UART2
的引脚是可以设置的。 UART1
默认引脚是GPIO9
用作U1RXD
,GPIO10
用作U1TXD
,但是这两个引脚也是用于外接flash的,因此在使用UART1
的时候需要设置其他引脚;
UART2
默认引脚是GPIO16
用作U2RXD
,GPIO17
用作U2TXD
。
2、API
在components/driver/include/driver/uart.h
中可以查看api;
在examples/peripherals/uart中也可以参考官方的各种串口例程。
2.1、安装uart驱动
1 |
esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int queue_size, QueueHandle_t* uart_queue, int intr_alloc_flags); |
这里要注意参数:uart_queue
属于freertos里面的队列句柄,在这里表示用于指示来自串口底层中断的队列消息。
2.2、uart参数配置
1 |
esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_config); |
2.3、接收阈值设置
1 |
esp_err_t uart_set_rx_full_threshold(uart_port_t uart_num, int threshold); |
2.4、串口引脚设置
1 |
esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num); |
2.5、从接收缓冲区读取数据
1 |
int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickType_t ticks_to_wait); |
2.6、数据写入发送缓冲区
1 |
int uart_write_bytes(uart_port_t uart_num, const char* src, size_t size); |
3、代码实现
3.1、参数定义
1 2 3 4 5 6 7 8 |
#define EX_UART_NUM UART_NUM_1 //串口1 #define TXD_PIN (GPIO_NUM_17) //txd使用gpio17 #define RXD_PIN (GPIO_NUM_16) //rxd使用gpio16 #define BUF_SIZE (128) //缓冲区定义 static QueueHandle_t uart_queue; //队列句柄 static uint8_t uartbuf[BUF_SIZE]; |
3.2、串口初始化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
void uart_comm_init(void) { /* Configure parameters of an UART driver, * communication pins and install the driver */ 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, }; //Install UART driver, and get the queue. uart_driver_install(EX_UART_NUM, BUF_SIZE * 2, BUF_SIZE * 2, 20, &uart_queue, 0); uart_param_config(EX_UART_NUM, &uart_config); uart_set_rx_full_threshold(EX_UART_NUM,126); //Set UART pins (using UART0 default pins ie no changes.) uart_set_pin(EX_UART_NUM, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); //Create a task to handler UART event from ISR xTaskCreate(uart_event_task, "uart_event_task", 2048, NULL, 12, NULL); //创建串口任务 } |
3.3、串口任务函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
static void uart_event_task(void *pvParameters) { uart_event_t event; for(;;) { //阻塞接收串口队列, //这个队列在底层发送,用户只需在应用层接收即可 if(xQueueReceive(uart_queue, (void * )&event, (portTickType)portMAX_DELAY)) { switch(event.type) {//各种串口事件 case UART_DATA: ESP_LOGI(TAG, "[UART DATA]: %d", event.size); uart_read_bytes(EX_UART_NUM, uartbuf, event.size, portMAX_DELAY); //阻塞接收 ESP_LOGI(TAG, "[DATA EVT]:"); uart_write_bytes(EX_UART_NUM, uartbuf, event.size);//原样发送 break; //Event of HW FIFO overflow detected case UART_FIFO_OVF: //硬件fifo溢出 ESP_LOGI(TAG, "hw fifo overflow"); // If fifo overflow happened, you should consider adding flow control for your application. // The ISR has already reset the rx FIFO, // As an example, we directly flush the rx buffer here in order to read more data. uart_flush_input(EX_UART_NUM); xQueueReset(uart_queue); break; //Event of UART ring buffer full case UART_BUFFER_FULL: //环形缓冲区满 ESP_LOGI(TAG, "ring buffer full"); // If buffer full happened, you should consider encreasing your buffer size // As an example, we directly flush the rx buffer here in order to read more data. uart_flush_input(EX_UART_NUM); xQueueReset(uart_queue); break; //Event of UART RX break detected case UART_BREAK: ESP_LOGI(TAG, "uart rx break"); break; //Event of UART parity check error case UART_PARITY_ERR: ESP_LOGI(TAG, "uart parity error"); break; //Event of UART frame error case UART_FRAME_ERR: ESP_LOGI(TAG, "uart frame error"); break; //UART_PATTERN_DET case UART_PATTERN_DET: break; //Others default: ESP_LOGI(TAG, "uart event type: %d", event.type); break; } } } vTaskDelete(NULL); } |
4、使用总结
- 初始化串口参数,(队列指针、缓冲区、引脚等);
- 任务中阻塞等待串口队列 。