OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3901|回复: 1

关于串口数据丢失的问题

[复制链接]

2

主题

5

帖子

0

精华

新手上路

积分
21
金钱
21
注册时间
2016-1-19
在线时间
6 小时
发表于 2016-1-20 17:00:15 | 显示全部楼层 |阅读模式
本帖最后由 ziqianCN 于 2016-1-20 17:04 编辑

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


------------------------------------
出问题的串口代码:
[mw_shl_code=c,true]printf("\r\n......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寄存器的状态,避免发送数据丢失。




正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

10

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1479
金钱
1479
注册时间
2016-1-25
在线时间
260 小时
发表于 2016-6-15 19:06:43 | 显示全部楼层
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-27 14:31

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表