02_ESP8266 NONOS_SDK 串口收发处理
一、创建工程:
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、串口接收处理过程