<p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/LearnESP32" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>
說明
模塊有3個串口,每個串口管腳可以設置到任意的gpio上
模組出廠默認使用GPIO1,GPIO3作為串口0引腳(日志打印); GPIO17,GPIO16作為串口1引腳(AT指令)
開發板上也把串口1連接了485上.
說明2
每個串口都有一個128字節的FIFO緩存區,知道這個就可以.
設置串口1,帶接收緩存,不帶發送緩存區的方式(最簡潔的方式)
設置GPIO17,GPIO16作為串口1引腳.
沒有設置發送緩存,調用 uart_write_bytes 發送數據的時候是阻塞的.
#include <stdio.h> #include <string.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/queue.h" #include "driver/gpio.h" #include "driver/timer.h" #include "esp_timer.h" #include "driver/uart.h" #define TXD1_PIN (GPIO_NUM_17) //串口1的發送數據引腳 #define RXD1_PIN (GPIO_NUM_16) //串口1的接收數據引腳 #define BUF_SIZE (1024) //接收數據緩存大小,該大小需要大於內部FIFO大小:UART_FIFO_LEN(128) /*串口任務*/ static void uart_task(void *arg) { /*配置串口參數*/ uart_config_t uart_config = { .baud_rate = 115200,//波特率 .data_bits = UART_DATA_8_BITS,//數據位8位 .parity = UART_PARITY_DISABLE,//無奇偶校驗 .stop_bits = UART_STOP_BITS_1,//停止位1位 .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,//不使用硬件流控 .source_clk = UART_SCLK_APB,//串口使用的時鍾 }; /*初始化串口1*/ uart_driver_install(UART_NUM_1, BUF_SIZE, //串口1接收緩存大小 0, //不使用發送緩存(發送數據的時候便會阻塞發送) 0, //隊列大小為0;沒有使用freertos內部緩存管理 NULL, //不使用QueueHandle_t 內部緩存管理,設置為空 0 //設置串口中斷優先級,設置為0意味着讓系統從1-3級中自動選擇一個 ); /*設置串口參數*/ uart_param_config(UART_NUM_1, &uart_config); /*設置串口的TX,RX,RTS,DTR引腳*/ //不使用RTS,DTR uart_set_pin(UART_NUM_1, TXD1_PIN, RXD1_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); /*申請一塊內存,用於臨時存儲接收的數據*/ uint8_t *data = (uint8_t *) malloc(BUF_SIZE); while (1) { //接收串口數據 //每隔10ms判斷一次,可以寫成portMAX_DELAY(一直判斷) int len = uart_read_bytes(UART_NUM_1, data, BUF_SIZE, 10 / portTICK_RATE_MS); //把接收的數據發送出去 uart_write_bytes(UART_NUM_1, (const char *) data, len); } } void app_main(void) { xTaskCreate(uart_task, "uart_task", 2048, NULL, 10, NULL); }
下載程序到開發板以后可以通過串口測試
485接口默認連接串口1,也可以使用485進行通訊
發送什么數據將會返回什么數據
設置串口1,帶接收緩存,帶發送緩存區的方式
設置上發送緩存區以后,調用 uart_write_bytes 發送數據的時候,將不會阻塞在那里.
設置串口1,帶接收緩存,帶發送緩存區,並使用上freertos內部的緩存管理的方式
加上緩存管理
從緩存管理中獲取數據
#include <stdio.h> #include <string.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/queue.h" #include "driver/gpio.h" #include "driver/timer.h" #include "esp_timer.h" #include "driver/uart.h" #define TXD1_PIN (GPIO_NUM_17) //串口1的發送數據引腳 #define RXD1_PIN (GPIO_NUM_16) //串口1的接收數據引腳 #define BUF_SIZE (1024) //接收數據緩存大小,該大小需要大於內部FIFO大小:UART_FIFO_LEN(128) #define BUF_SEND_SIZE (1024) //發送數據緩存大小,該大小需要大於內部FIFO大小:UART_FIFO_LEN(128) static QueueHandle_t QueueHandle_t_uart1; /*串口任務*/ static void uart_task(void *arg) { /*配置串口參數*/ uart_config_t uart_config = { .baud_rate = 115200,//波特率 .data_bits = UART_DATA_8_BITS,//數據位8位 .parity = UART_PARITY_DISABLE,//無奇偶校驗 .stop_bits = UART_STOP_BITS_1,//停止位1位 .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,//不使用硬件流控 .source_clk = UART_SCLK_APB,//串口使用的時鍾 }; /*初始化串口1*/ uart_driver_install(UART_NUM_1, BUF_SIZE, //串口1接收緩存大小 BUF_SEND_SIZE, //串口1發送緩存大小 10, //隊列大小為10 &QueueHandle_t_uart1, //緩存管理 0 //設置串口中斷優先級,設置為0意味着讓系統從1-3級中自動選擇一個 ); /*設置串口參數*/ uart_param_config(UART_NUM_1, &uart_config); /*設置串口的TX,RX,RTS,DTR引腳*/ //不使用RTS,DTR uart_set_pin(UART_NUM_1, TXD1_PIN, RXD1_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); /*申請一塊內存,用於臨時存儲接收的數據*/ uint8_t *data = (uint8_t *) malloc(BUF_SIZE); uart_event_t event; while (1) { if(xQueueReceive(QueueHandle_t_uart1, (void * )&event, portMAX_DELAY)) { switch(event.type) { case UART_DATA://接收到數據 //讀取接收的數據 uart_read_bytes(UART_NUM_1, data, event.size, portMAX_DELAY); //返回接收的數據 uart_write_bytes(UART_NUM_1, (const char*) data, event.size); break; case UART_FIFO_OVF://FIFO溢出(建議加上數據流控制) uart_flush_input(UART_NUM_1); xQueueReset(QueueHandle_t_uart1); break; case UART_BUFFER_FULL://接收緩存滿(建議加大緩存 BUF_SIZE) uart_flush_input(UART_NUM_1); xQueueReset(QueueHandle_t_uart1); break; case UART_BREAK://檢測到接收數據中斷 break; case UART_PARITY_ERR://數據校驗錯誤 break; case UART_FRAME_ERR://數據幀錯誤 break; case UART_PATTERN_DET://接收到相匹配的字符(沒用到) break; default: break; } } } free(data); data = NULL; vTaskDelete(NULL); } void app_main(void) { xTaskCreate(uart_task, "uart_task", 2048, NULL, 10, NULL); }
如果想配置串口0或者串口2
把以下變量的最后一個數字改為0或者2即可
關於模式匹配和485方向控制,參考
https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-reference/peripherals/uart.html?highlight=uart_pattern_det#
官方文檔