单片机串口接收不定长数据时,必须面对的一个问题为:怎么判断这一包数据接收完成了呢?常见的方法主要有以下两种:

1.在接收数据时启动一个定时器,在指定时间间隔内没有接收到新数据,认为数据接收完成;2.在数据中加入帧头、帧尾,通过在程序中判断是否接收到帧尾来确定数据接收完毕。这两种方法的缺点为,需要主程序来判断和处理,对主程序造成不小压力。

1)在串口接收的时候,有些通讯每一帧数据有帧头尾标识,这种情况比较好判定。但是也有些情况是,头尾没有固定的标识,也不知道一帧有多少字节,那么我们只能靠检测帧之间的间隔来判断是不是帧完成了。

例串口设置:9600波特率、8个数据位、1个停止位、无校验。

9600波特率表示,每秒传输9600个位,即每秒传输9600/(8位数据位+1位停止)=1066字节,

那么每秒传输一个字节的时间就是:1/1066=9.38*10^-4s≈0.94ms;

考虑硬件的损耗,保证数据传输的可靠性,留出余量,假设一个字节的传输时间为2ms。

例如波特率为9600,则说明每秒钟可以传输9600个二进制位,即传输一个二进制位需要的时间为1/9600秒。

那么我们就可以配置定时器,通过对时间的判断识别接收一帧未知长度的串口数据,

以定时2ms来说,当接收到一个字节的时候,我们打开定时器,开始计时,定时周期2ms。

如果过了2ms,没有新数据,那么我们认为一帧数据接收完成。

如果在2ms这个时间内,有新数据到来,那么我们认为是同一帧数据,此时定时器计数清零,重新计数。

初始化定义:一个足够大数组和一个记录字节数的变量。

3.使用单片机的串口空闲中断;
1)开启串口空闲中断;
2)在串口中断中判断是否是串口空闲中断,清除串口空闲中断的标志位。