105-ESP32_SDK開發-串口,485通信


<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#

 

 

 

 

 

官方文檔

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM