ESP8266学习笔记(一)UART接受发送
注:该帖为自己在使用stm32时的问题总结贴,如有错误欢迎大家指正出来,一起交流学习
一、简介 ESP8266 有两个UART。UART0有TX、RX作为 系统的打印信息输出接口 和 数据收发口,而UART1只有TX,作为 打印信息输出接口(调试用)。
文章图片
【ESP8266学习笔记(一)UART接受发送】
二、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()
推荐阅读
- EffectiveObjective-C2.0|EffectiveObjective-C2.0 笔记 - 第二部分
- 由浅入深理解AOP
- 继续努力,自主学习家庭Day135(20181015)
- python学习之|python学习之 实现QQ自动发送消息
- Android中的AES加密-下
- 一起来学习C语言的字符串转换函数
- 定制一套英文学习方案
- 漫画初学者如何学习漫画背景的透视画法(这篇教程请收藏好了!)
- 《深度倾听》第5天──「RIA学习力」便签输出第16期
- 如何更好的去学习