关于串口数据丢失的问题

2019-07-20 21:44发布

本帖最后由 ziqianCN 于 2016-1-20 17:04 编辑

在使用串口发送数据时,当程序中使用for循环发送数据时,常常会丢失数据,刚好今天碰到printf之后发送数据的情况,结果发现printf的最后一个数据内容丢失,
于是查看了关于printf的代码,发现问题了


------------------------------------
出问题的串口代码:
[mw_shl_code=c,true]printf(" ......Data(内容)");
    for(i=0;i<RxMessage.DLC;i++){
        USART_SendData(USART1,RxMessage.Data);//循环发送,直到发送完毕
    }[/mw_shl_code]

结果输出为:......Data(内容NOPQRST
即printf的最后一个数据丢失了,然后找到原子哥重写的fputc源头,发现问题出在这儿,因为printf保证了发送之前串口内容已发送,
但是如果后面其他地方使用串口的时候并未提前使用while((USART1->SR&0X40)==0);检查,就不能保证printf的最后一个数据也正确发送。

----------------------------------------------
usart.c中关于printf的代码:

[mw_shl_code=c,true]//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8) ch;
return ch;
}[/mw_shl_code]

将以上代码做了修改,将while循环调至后面,问题解决。
[mw_shl_code=c,true]USART1->DR = (u8) ch;
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕 [/mw_shl_code]

但是这样做,printf第一个数据发送前并未做检查,可能造成覆盖了前面未发送完成的数据,造成其他的数据丢失,
如果安全起见,就需要前后都添加while循环判断,

[mw_shl_code=c,true]while((USART1->SR&0X40)==0);//循环发送,直到本次开始使用串口之前的数据发送完毕
USART1->DR = (u8) ch;
while((USART1->SR&0X40)==0);//循环发送,直到本次写入数据发送完毕 [/mw_shl_code]

但是这样两次循环判断会造成资源浪费,但是又不知道之前对串口的使用是否做了类似循环处理,
所以为了避免本次发送数据的丢失,同时又有利于提高效率,最妥当的办法还是上面一种方法,
提醒大家:使用串口发送数据时,USART_SendData或者USART1->DR = (u8) ch之前一定要先检查SR寄存器的状态,避免发送数据丢失。




友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。