小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

基于ESP32的uart通訊

 iamlijin 2019-08-07

  本文源碼地址為:http://download.csdn.net/download/noticeable/9961054

  ESP32上有三個(gè)UART通訊接口,設(shè)備號(hào),從0~2,即UART0,UART1,UART2。支持異步通訊,ESP32開發(fā)板上micro USB  連接的即使UART0接口,通常使用該串口作為日志輸出,用于調(diào)試,另外兩個(gè)串口作為工作串口,可用來輸出和接收數(shù)據(jù)。

對(duì)于uart通訊,主要可以分為以下幾個(gè)部分:

PART1:

定義引腳

復(fù)制代碼
1 #ifndef size_t
2 #define size_t unsigned int
3 #endif
4 #define BUF_SIZE (1024)
5 #define ECHO_TEST_TXD  (4)
6 #define ECHO_TEST_RXD  (5)
7 #define ECHO_TEST_RTS  (18)
8 #define ECHO_TEST_CTS  (19)
9 QueueHandle_t uart0_queue;
復(fù)制代碼

定義引腳,這里TXD、RXD是串口輸出通常用到數(shù)據(jù)寫出和讀入的引腳,關(guān)于RTS和CTS引腳 (注意:由于UART0已經(jīng)的引腳配置已經(jīng)固定默認(rèn)在BootLoader中了,不能更改,所以不能配置引腳也無需定義)

  RTS(Request To Send 請(qǐng)求發(fā)送):用于傳輸PC機(jī)發(fā)往串口Modem等設(shè)備的信號(hào),該信號(hào)表示PC機(jī)是否允許Modem發(fā)數(shù)據(jù)。
  CTS:Clear to send,在計(jì)算機(jī)UART引腳中定義表示為允許發(fā)送。
在與計(jì)算機(jī)通訊過程中常與RTS( request to send, 請(qǐng)求發(fā)送信號(hào) )一起被提到,是UART通訊過程中flow control的兩個(gè)引腳,是成對(duì)出現(xiàn)的。
下面說一下這兩個(gè)引腳的作用;
 ?。?) 隱藏終端問題被減輕了,因?yàn)殚Ldata幀只有在信道預(yù)約后才能被發(fā)送;
 ?。?)因?yàn)閞ts幀和cts幀較短,涉及rts幀和cts幀的碰撞將僅持續(xù)很短的rts幀或cts幀持續(xù)期。一旦rts幀和cts幀被正確傳輸,后續(xù)的data幀和ack幀應(yīng)當(dāng)能無碰撞的發(fā)送。

PART2:編寫uart處理任務(wù)

復(fù)制代碼
 1 void uart_task(void *pvParameters)
 2 {
 3     int uart_num = (int) pvParameters;
 4     uart_event_t event;
 5     size_t buffered_size;
 6     uint8_t* dtmp = (uint8_t*) malloc(BUF_SIZE);
 7     for(;;) {
 8         //Waiting for UART event.
 9         if(xQueueReceive(uart0_queue, (void * )&event, (portTickType)portMAX_DELAY)) {
10             ESP_LOGI(TAG, "uart[%d] event:", uart_num);
11             switch(event.type) {
12                 //Event of UART receving data
13                 /*We'd better handler data event fast, there would be much more data events than
14                 other types of events. If we take too much time on data event, the queue might
15                 be full.
16                 in this example, we don't process data in event, but read data outside.*/
17                 case UART_DATA:
18                     uart_get_buffered_data_len(uart_num, &buffered_size);
19                     ESP_LOGI(TAG, "data, len: %d; buffered len: %d", event.size, buffered_size);
20                     break;
21                 //Event of HW FIFO overflow detected
22                 case UART_FIFO_OVF:
23                     ESP_LOGI(TAG, "hw fifo overflow\n");
24                     //If fifo overflow happened, you should consider adding flow control for your application.
25                     //We can read data out out the buffer, or directly flush the rx buffer.
26                     uart_flush(uart_num);
27                     break;
28                 //Event of UART ring buffer full
29                 case UART_BUFFER_FULL:
30                     ESP_LOGI(TAG, "ring buffer full\n");
31                     //If buffer full happened, you should consider encreasing your buffer size
32                     //We can read data out out the buffer, or directly flush the rx buffer.
33                     uart_flush(uart_num);
34                     break;
35                 //Event of UART RX break detected
36                 case UART_BREAK:
37                     ESP_LOGI(TAG, "uart rx break\n");
38                     break;
39                 //Event of UART parity check error
40                 case UART_PARITY_ERR:
41                     ESP_LOGI(TAG, "uart parity error\n");
42                     break;
43                 //Event of UART frame error
44                 case UART_FRAME_ERR:
45                     ESP_LOGI(TAG, "uart frame error\n");
46                     break;
47                 //UART_PATTERN_DET
48                 case UART_PATTERN_DET:
49                     ESP_LOGI(TAG, "uart pattern detected\n");
50                     break;
51                 //Others
52                 default:
53                     ESP_LOGI(TAG, "uart event type: %d\n", event.type);
54                     break;
55             }
56         }
57     }
58     free(dtmp);
59     dtmp = NULL;
60     vTaskDelete(NULL);
61 }
復(fù)制代碼

 

   uart_task任務(wù)的作用為對(duì)接收到的數(shù)據(jù)進(jìn)行處理,并將結(jié)果通過日志的形式打印到串口調(diào)試助手上,最后在任務(wù)結(jié)束時(shí),將處理任務(wù)刪除掉。


PART3:

編寫uart0 配置函數(shù)

復(fù)制代碼
 1 void uart_evt_test()
 2 {
 3     int uart_num = UART_NUM_0;
 4     uart_config_t uart_config = {
 5        .baud_rate = 115200,
 6        .data_bits = UART_DATA_8_BITS,
 7        .parity = UART_PARITY_DISABLE,
 8        .stop_bits = UART_STOP_BITS_1,
 9        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
10        .rx_flow_ctrl_thresh = 122,
11     };
12     //Set UART parameters
13     uart_param_config(uart_num, &uart_config);
14     //Set UART log level
15     esp_log_level_set(TAG, ESP_LOG_INFO);
16     //Install UART driver, and get the queue.
17     uart_driver_install(uart_num, BUF_SIZE * 2, BUF_SIZE * 2, 10, &uart0_queue, 0);
18     //Set UART pins,(-1: default pin, no change.)
19     //For UART0, we can just use the default pins.
20     //uart_set_pin(uart_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
21     //Set uart pattern detect function.
22     uart_enable_pattern_det_intr(uart_num, '+', 3, 10000, 10, 10);
23     //Create a task to handler UART event from ISR
24     xTaskCreate(uart_task, "uart_task", 2048, (void*)uart_num, 12, NULL);
25     //process data
26     uint8_t* data = (uint8_t*) malloc(BUF_SIZE);
27     do {
28         int len = uart_read_bytes(uart_num, data, BUF_SIZE, 100 / portTICK_RATE_MS);
29         if(len > 0) {
30             ESP_LOGI(TAG, "uart read : %d", len);
31             uart_write_bytes(uart_num, (const char*)data, len);
32         }
33     } while(1);
34 }
復(fù)制代碼

 

  uart_event_test函數(shù),用來對(duì)uart進(jìn)行配置其中
    uart_num  設(shè)置UART外設(shè)號(hào)碼,可選位UART_NUM_0 、UART_NUM_1、UART_NUM_2  
    baud_rate  設(shè)置波特率    可選為:
    data_bits  設(shè)置數(shù)據(jù)位寬
    parity    是否校驗(yàn)      UART_PARITY_DISABLE禁用UART奇偶校驗(yàn),UART_PARITY_EVEN啟用UART偶校驗(yàn),UART_PARITY_ODD 啟用UART奇校驗(yàn)
    stop_bits   停止位位數(shù)    
    flow_ctrl   UART硬件流控制模式    UART_HW_FLOWCTRL_DISABLE 禁用硬件流控制,UART_HW_FLOWCTRL_RTS 啟用RX硬件流控制(rts),UART_HW_FLOWCTRL_CTS 啟用TX硬件流控制,UART_HW_FLOWCTRL_CTS_RTS 啟用硬件流控制。
    rx_flow_ctrl_thresh 硬件流控制的閾值。
最后調(diào)用   uart_param_config(uart_num, &uart_config);對(duì)uart參數(shù)進(jìn)行設(shè)定
         esp_log_level_set(TAG, ESP_LOG_INFO);對(duì)esp32的輸出日志設(shè)置級(jí)別,這里將uart example設(shè)置為正常的流和事件作為日志輸出。
            uart_driver_install(uart_num, BUF_SIZE * 2, BUF_SIZE * 2, 10, &uart0_queue, 0);安裝UART驅(qū)動(dòng)程序。UART ISR處理程序?qū)⒏郊拥皆摴δ苷谶\(yùn)行的同一CPU內(nèi)核。
            uart_enable_pattern_det_intr(uart_num, '+', 3, 10000, 10, 10);  UART使能模式檢測功能。專為“AT命令”等應(yīng)用程序而設(shè)計(jì)。當(dāng)硬件檢測到一系列相同的字符時(shí),中斷將被觸發(fā)。
                 xTaskCreate(uart_task, "uart_task", 2048, (void*)uart_num, 12, NULL);   調(diào)用uart_task 任務(wù),對(duì)接收到的數(shù)據(jù)相關(guān)的長度等信息進(jìn)行打印。
            其后的任務(wù)即為處理接收到的數(shù)據(jù),并將數(shù)據(jù)打印出來,并等待。
    函數(shù)的作用是配置了uart0的工作模式,并通過聲明了的uart0_queue消息隊(duì)列接收信息,并在調(diào)用uart_driver_install注冊串口時(shí)將消息隊(duì)列傳遞到層,當(dāng)有串口消息來時(shí),串口消息隊(duì)列會(huì)發(fā)送消息到該消息隊(duì)列,然后通過uart_task接收串口數(shù)據(jù),如果檢測到入伍中有消息隊(duì)列則讀串口。
    可以看出,uart0的通訊方式是有消息來了才接收,所以其為異步通訊方式。

PART4:

編寫uart1配置函數(shù)

復(fù)制代碼
 1 void uart_echo_test()
 2 {
 3     int uart_num = UART_NUM_1;
 4     uart_config_t uart_config = {
 5         .baud_rate = 115200,
 6         .data_bits = UART_DATA_8_BITS,
 7         .parity = UART_PARITY_DISABLE,
 8         .stop_bits = UART_STOP_BITS_1,
 9         .flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS,
10         .rx_flow_ctrl_thresh = 122,
11     };
12     //Configure UART1 parameters
13     uart_param_config(uart_num, &uart_config);
14     //Set UART1 pins(TX: IO4, RX: I05, RTS: IO18, CTS: IO19)
15     uart_set_pin(uart_num, ECHO_TEST_TXD, ECHO_TEST_RXD, ECHO_TEST_RTS, ECHO_TEST_CTS);
16     //Install UART driver( We don't need an event queue here)
17     //In this example we don't even use a buffer for sending data.
18     uart_driver_install(uart_num, BUF_SIZE * 2, 0, 0, NULL, 0);
19 
20     uint8_t* data = (uint8_t*) malloc(BUF_SIZE);
21     while(1) {
22         //Read data from UART
23         int len = uart_read_bytes(uart_num, data, BUF_SIZE, 20 / portTICK_RATE_MS);
24         //Write data back to UART
25         uart_write_bytes(uart_num, (const char*) data, len);
26     }
27 }
復(fù)制代碼

 

    對(duì)于uart1,其大致過程與uart0函數(shù)是相似的,但是不同點(diǎn)在與其通訊模式與uart0是不同的,第9行可以看出它是通過硬件流進(jìn)行通訊的。

PART5:

app_main函數(shù)

復(fù)制代碼
1 void app_main()
2 {
3     //A uart read/write example without event queue;
4     xTaskCreate(uart_echo_test, "uart_echo_test", 1024, NULL, 10, NULL);
5 
6     //A uart example with event queue.
7     uart_evt_test();
8 }
復(fù)制代碼

 

通過app_main對(duì)兩個(gè)函數(shù)進(jìn)行調(diào)用。

 

實(shí)驗(yàn)現(xiàn)象:

    由于本人手上沒有硬件流相關(guān)的串口調(diào)試器,所以對(duì)于uart1的驗(yàn)證無法進(jìn)行了,這里只對(duì)uart0的結(jié)果進(jìn)行實(shí)驗(yàn)。

    打開串口調(diào)試助手,連接esp32(通過usb直接連接即可),發(fā)送數(shù)據(jù),可以得到如下結(jié)果。說明串口數(shù)據(jù)發(fā)送成功。

 

 

 

相關(guān)知識(shí):UART相關(guān)API接口








    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多