ESP32串口的正确打开方式

之前写过一篇关于esp32串口的文章:ESP32中断方式操作串口,但是不够详细,这篇进行更加细节的描述。

因为我这个代码是基于micropython esp32进行二次开发的,需要改造原有micropython对串口的配置。当然这些代码直接用ESP32-IDF开发也没问题。

先看下Micropython对ESP32uart0的串口配置:

对应文件为:/micropython/ports/esp32/uart.c

该文件初始化打开了串口接收中断,但是没有安装串口驱动,所以不能在中断服务函数中调用uart_write_bytes()。如果要要调用该发送函数,必须在串口初始化的时候,执行如下两步:

该函数主要执行两个步骤:

  • 串口中断服务函数的注册
  • 串口接收中断的使能,接收中断使能函数里面打开了两个中断FIFO 接收满和接收超时中断

如上是我们解释一下micropython对串口的配置,但不是重点,重点还在于我们自己的初始化和中断服务函数代码:

完整的串口初始化配置

该初始化主要执行以下几个步骤:

  • 串口参数的初始化配置
  • 串口引脚配置
  • 串口驱动安装,这个地方需要注意,执行完uart_driver_install以后,默认会使用ESP32-IDF自带的串口中断服务函数,而这里我们不是用就需要下一步操作
  • 释放idf自带串口中断服务函数
  • 重新注册自定义串口中断服务函数
  • 使能串口接收中断uart_enable_rx_intr,该函数会打开两个中断源:rxfifo接收满中断,rxfifo超时中断(默认超时时间为10个byte)
  • 最后一步设置接收超时中断时间可以省略,因为在上一步已经默认打开,并且idf默认值为10个bytes时间。如果想修改超时中断时间的话就调用该函数

完整的串口中断服务函数

初始化已经打开了串口中断,针对接收有两个中断源:rxfifo满中断 rx接收超时中断。默认rxfifo的深度为128byte,所以只要不连续发超过128个byte都不会触发fifo满中断。当发送完一帧数据,只要后面空闲的时间超过设定的超时时间就会产生超时中断。所以这里要弄清楚并不是每接收到一个byte就会产生一次串口中断。
在实际测试中,给ESP32发送一帧数据会让他触发两次rx超时中断,详述如下

关于esp32 串口接收超时中断

IDF中设置默认超时时间为,10代表以当前波特率传输10bytes的时间

每接收一帧连续的数据包,会触发两次超时中断。

  • 第一次触发超时中断,读取rxfifo中已接收字节数和这一帧数据长度相等。
  • 第二次触发超时中断,读取rxfilo已接收字节数为0

所以只要每一帧数据之间都有时间空隙,并且空隙时间长于设定值,那么第一次触发超时中断时rxfifo中的数据就是一帧的数据。读取UART0.status.rxfifo_cnt该寄存器里面的值就是这一帧的数据包长度值

您可能还喜欢...

4 条回复

  1. shengfeng1991说道:

    你好,为什么用你这种方法,中断接收数据时,会复位。