利用Idle中断实现UART未知数据的不定长度接收
前言
我们在使用UART进行通信的时候,一般是使用协议来控制数据包,DMA接收时则是约定固定长度的数据包来收发。但是也经常有用到未知数据的不定长度接收数据,平时实现不定长度接收时很麻烦,因为我们不知道发送端过来的数据长度,常常是设置接收超时来实现,这样无法保证最高的传输效率。
实现原理
现在很多MCU的UART外设,具有一个Idle中断功能。这个Idle功能一般是指串口线接收启动后,当一帧数据传输完成时,线上会维持高电平空闲,此时会触发UART外设的IDLE中断。配置好UART,在接收数据之前清除Idle状态,使能idle中断,尽管此时线上也是高电平,但这个Idle中断在接收数据之前不会产生。等一帧数据接收完,线上的高电平(空闲)到达一定时间(一般是1-2个byte)后,认为当前数据接收结束,产生idle标志。通过idle中断处理函数结束当前接收,此时完成一次接收。通过这个方法可以实现不定长的数据接收,可以用于中断和DMA的不定长数据接收实现。
实现举例
我们拿STM32系列芯片来举例,来实现串口DMA的不定长数据接收。
- 在启动UART的DMA接收函数后,马上清除idle中断,然后使能idle中断;
- 在中断处理函数里面增加idle中断处理,放在接收读取函数之后,进入idle中断后根据预期接收的数据字节数和DMA传输长度中剩余的字节数计算得到已经接收到的字节数,然后终止当前DMA接收即可。