一、創建工程:
1、引用模板
引用上節的工程模板,改名UART-HelloWorld 。
2、復制uart.c文件
下載未處理過的ESP8266_NONOS_SDK-2.2.1 ,將ESP8266_NONOS_SDK-2.2.1\driver_lib\driver文件夾里的uart.c 拷貝至UART-HelloWorld/APP/driver里面。
3、復制uart.h、uart_register.h文件
將ESP8266_NONOS_SDK-2.2.1\driver_lib\include\driver文件夾里的uart.h、uart_register.h 拷貝至UART-HelloWord\app\include\driver里面。
4、了解8266的串口
(1)ESP8266-12f 有兩個 UART :
UART0 有 TX、RX,可做數據傳輸;
UART1 由於 RX 腳被 SPI-Flash 占用,只能使用 TX,可以做串口調試信息打印。見下圖:串口一是在GPIO2,只可以查看信息。
UART0 為串口1,TXD0 -->GPIO1 , TXD1 -->GPIO3 ,而UART1的TXD1--> GPIO2
5、串口打印
6、燒錄
7、串口助手查看
ESP-12F 晶振26MHz 波特率默認為74880 ,若想設置UART波特率、參數等,則要在user_main.c中引用串口頭文件 #include "driver/uart.h"
uart.h文件中:
在主函數,初始串口波特率:
二、串口接收:
1、串口初始化
串口初始化函數里面有兩個函數,system_os_task函數和uart_config(UART0)需要注意的。
1.1 system_os_task函數
system_os_task(uart_recvTask, uart_recvTaskPrio, uart_recvTaskQueue, uart_recvTaskQueueLen);
這個函數創建一個任務,就是用於處理串口0的接收數據。
上面函數創建了一個uart_recvTask函數任務,這個函數是為了處理接受數據。如下:
1.2 uart_config(UART0) 函數
uart_config(UART0) //串口配置函數
在uart_config(UART0)函數里面,有一個ETS_UART_INTR_ATTACH 函數,利用ETS_UART_INTR_ATTACH函數設置了串口的回調函數 uart0_rx_intr_handler 。
ETS_UART_INTR_ATTACH(uart0_rx_intr_handler, &(UartDev.rcv_buff)); //串口0
1.2.1 uart0_rx_intr_handler函數
在uart0_rx_intr_handler里面有各種中斷的標志判斷,當串口接收中斷發生時,FIFO滿了或FIFO超時了,都會使得中斷向任務發送消息,從而執行任務中的接收任務事件。
在滿中斷和超時中斷時,system_os_post發送了一個信號,於是進入uart_recvTask函數,我們在這個函數里面寫串口接受數據處理。
//=========================================================================================================================== //上述uart0_rx_intr_handler函數中,在滿中斷和超時中斷時,system_os_post發送了一個信號,於是進入uart_recvTask函數。 LOCAL void ICACHE_FLASH_ATTR uart_recvTask(os_event_t *events) { if(events->sig == 0){ #if UART_BUFF_EN //UART_BUFF_EN定義為了 0,當前為0,不為1,所以執行else后面程序 //函數主要功能:把接收的數據保存到pRxBuffer(pRxBuffer是個環形緩存)里,然后我們可以對pRxBuffer進行解析,進而來處理接收的內容 Uart_rx_buff_enq(); #else // 1.從先進先出通道 FIFO 讀取接收到的數據長度 uint8 fifo_len = (READ_PERI_REG(UART_STATUS(UART0))>>UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT; uint8 d_tmp = 0; uint8 idx=0; //奮創建的語句:------------------------------------------------ // 2.定義一個臨時接收的數據區 uint8 uartRxBuffer[fifo_len]; //---------------------------------------------------------。 // 3. 賦值給臨時數組 for(idx=0;idx<fifo_len;idx++) { d_tmp = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF;// 根據數據長度一個一個讀取數據 uart_tx_one_char(UART0, d_tmp); //在這個里面就是把接收到的數據通過 uart_tx_one_char(UART0, d_tmp);一個個的發送出來,如果我們想處理 自己接收的數據,只要把它放到緩沖區就處理就可以。 //奮創建的語句:------------------------------------------------ // 將接收到的值存儲到數組 uartRxBuffer[idx] = d_tmp; //---------------------------------------------------------。 } // 4.做你自己的事情,uartRxBuffer[]數組就是接收到的數據 //奮創建的語句:------------------------------------------------ if(uartRxBuffer[0]=='z'&&uartRxBuffer[1]=='f'&&uartRxBuffer[2]=='f') { os_printf("you input frank\r\n"); uart0_tx_buffer("zff\r\n",os_strlen("frank\r\n")); } //---------------------------------------------------------。 //清除中斷寄存器的 滿中斷位 或 超時中斷位 WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR|UART_RXFIFO_TOUT_INT_CLR); // 5.UART0接收中斷使能 uart_rx_intr_enable(UART0); #endif }else if(events->sig == 1){ #if UART_BUFF_EN //already move uart buffer output to uart empty interrupt //tx_start_uart_buffer(UART0); #else #endif } }
2、串口接收處理過程