ESP8266学习笔记(9) 您所在的位置:网站首页 串口通信介绍怎么写 ESP8266学习笔记(9)

ESP8266学习笔记(9)

2023-05-13 10:46| 来源: 网络整理| 查看: 265

开启掘金成长之旅!这是我参与「掘金日新计划 · 4 月更文挑战」的第 25 天,点击查看活动详情

一、简介

ESP8266 有两个UART。UART0有TX、RX作为 系统的打印信息输出接口 和 数据收发口,而UART1只有TX,作为 打印信息输出接口(调试用)。

二、UART0接收 2.1 相关函数

在 /driver/uart.c 中,

2.1.1 uart0_rx_intr_handler

用于UART0中断处理,用户可在该函数内添加对接收到数据包的处理。

LOCAL void uart0_rx_intr_handler(void *para) { /* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents * uart1 and uart0 respectively */ uint8 RcvChar; uint8 uart_no = UART0;//UartDev.buff_uart_no; uint8 fifo_len = 0; uint8 buf_idx = 0; uint8 temp,cnt; //RcvMsgBuff *pRxBuff = (RcvMsgBuff *)para; /* 注意: */ // 不要在中断处理函数中调用带有 "ICACHE_FLASH_ATTR" 宏的函数,否则将引起异常。 /*ALL THE FUNCTIONS CALLED IN INTERRUPT HANDLER MUST BE DECLARED IN RAM */ /*IF NOT , POST AN EVENT AND PROCESS IN SYSTEM TASK */ // 接收帧错误中断 if(UART_FRM_ERR_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_FRM_ERR_INT_ST)) { WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_FRM_ERR_INT_CLR); // 清除中断寄存器的 帧错误位 } // 接收满中断 FULL else if(UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST)) { uart_rx_intr_disable(UART0); // 1. 接收中断禁用,用于不再接受数据,因为现在处于处理数据中 WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR); // 2.清除中断寄存器的 接收 FULL 位 system_os_post(uart_recvTaskPrio, 0, 0); // 3.向任务函数发送消息 } // 接收超时中断 TOUT else if(UART_RXFIFO_TOUT_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_TOUT_INT_ST)) { uart_rx_intr_disable(UART0); // 1. 接收中断禁用,用于不再接受数据,因为现在处于处理数据中 WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_TOUT_INT_CLR); // 2.清除中断寄存器的 接收超时中断位 system_os_post(uart_recvTaskPrio, 0, 0); // 3.向任务函数发送消息 } // 发送 FIFO 空中断 else if(UART_TXFIFO_EMPTY_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_TXFIFO_EMPTY_INT_ST)) { /* to output uart data from uart buffer directly in empty interrupt handler*/ /*instead of processing in system event, in order not to wait for current task/function to quit */ /*ATTENTION:*/ /*IN NON-OS VERSION SDK, DO NOT USE "ICACHE_FLASH_ATTR" FUNCTIONS IN THE WHOLE HANDLER PROCESS*/ /*ALL THE FUNCTIONS CALLED IN INTERRUPT HANDLER MUST BE DECLARED IN RAM */ CLEAR_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA);// 清楚中断标志 //system_os_post(uart_recvTaskPrio, 1, 0); WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_TXFIFO_EMPTY_INT_CLR); // 清除中断寄存器的 发送 FIFO 空中断位 } // 接收溢出中断 else if(UART_RXFIFO_OVF_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_OVF_INT_ST)) { WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_OVF_INT_CLR); // 清除中断寄存器的 接收溢出中断位 } } 复制代码 2.1.2 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) { // 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[256] = {0}; // 3. 赋值给临时数组 for(idx = 0; idx < fifo_len; idx++) { d_tmp = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF; // 根据数据长度一个一个读取数据 uartRxBuffer[idx] = d_tmp; // 赋值 } // 4.做你自己的事情,uartRxBuffer[]数组就是接收到的数据 { ... ... } // 清除中断寄存器的 满中断位 或 超时中断位 WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR|UART_RXFIFO_TOUT_INT_CLR); // 5.UART0接收中断使能 uart_rx_intr_enable(UART0); } else if(events->sig == 1) { } } 复制代码 2.2 使用流程

①串口初始化

uart_init(115200, 115200); // 设置串口0和串口1的波特率

②串口中断处理

uart0_rx_intr_handler(void *para); // UART0 中断处理函数,在此用作中断触发类型的判断

主要修改下面这个函数

uart_recvTask(os_event_t *events) // UART0 中断处理函数,在此用作中断接收数据处理

三、UART0发送 3.1 相关函数

3.2 使用流程

①串口初始化 uart_init(115200, 115200); // 设置串口0和串口1的波特率 ②串口发送数据 uart0_tx_buffer(void *buf, uint16 len); // UART0 发送数据函数

四、UART1发送 4.1 相关函数

在 /driver/uart.c 中,

4.1.1 UART_SetPrintPort

用于设置打印调试信息的串口

void ICACHE_FLASH_ATTR UART_SetPrintPort(uint8 uart_no) { if(uart_no==1){ os_install_putc1(uart1_write_char); }else{ /*option 1: do not wait if uart fifo is full,drop current character*/ os_install_putc1(uart0_write_char_no_wait); /*option 2: wait for a while if uart fifo is full*/ os_install_putc1(uart0_write_char); } } 复制代码 4.1.2 uart1_sendStr_no_wait

用于串口1输出一串字符

void uart1_sendStr_no_wait(const char *str) { while(*str){ uart_tx_one_char_no_wait(UART1, *str++); } } 复制代码 3.2 使用流程

①串口初始化

uart_init(115200, 115200); // 设置串口0和串口1的波特率

②设置调试串口

UART_SetPrintPort(UART1); // 使用串口1打印调试信息

③打印调试信息

os_printf()或uart1_sendStr_no_wait()

• 由 Leung 写于 2019 年 2 月 16 日

• 参考:Esp8266 进阶之路25【高级篇】深聊下esp8266的串口 Uart 通讯中断编程

    ESP8266 Non-OS SDK API参考[7qq6]

    ESP8266 技术参考[zj5o]



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有