一、引言

        在stm32中,一般采用的是通过数组来接收串口信息,但是由于受到数组大小的限制,易出现数据覆盖或者数据溢出问题。针对上述问题,采用循环队列的方式来接收串口信息,循环队列可以动态管理缓冲区并且当队列满时,能灵活选择覆盖旧数据或者丢弃新数据,从而避免了数据混乱问题。

二、代码实现

        队列是一种数据结构,有着先进先出的特性,因此需要两个指针,一个指针用于入队,它要指向最后一个元素;一个指针用于出队,它指向第一个元素。因此我们可以通过c语言定义出这个数据类型,如下图所示,将其写在了queue.h头文件里边。

        其中,in指针用于入队,out指针用于出队,size代表的是当前队列容量,capicity是整个队列缓冲区大小。接下来需要编写队列初始化函数、判断队列满或空函数、入队函数及出队函数,如下图所示:

        其中,q->in=(q->in+1)%capicity;这一行代码是为了当数组满时,重新从下标0开始。接下来编写串口初始化函数,如下图所示:

        编写串口接收中断函数,如下图所示:

        中断函数主要就是在接收到数据以后,存在队列里边。接下来看对接收到的串口数据的处理,先定义队列结构体变量q,然后去进行处理,如下图所示:

总结

        循环队列通过分离读写指针和缓冲区满检测机制,有效解决了串口通过数组接收数据中的覆盖问题,具体区别如下表所示:

特性循环队列传统数组
数据覆盖缓冲区满时拒绝新数据新数据覆盖旧数据
内存利用率循环利用内存空间线性使用,效率低
数据处理中断仅写入,主循环处理中断中处理或标记
实现复杂度中等(需要管理指针)简单
数据丢失可控(可记录溢出)不可控(静默覆盖)
适用场景高速数据流、大数据量低速通信、小数据包

 

更多推荐