OpenEdv-开源电子网

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

【原创】STM32 ZET6 硬件置位后,串口(USART)发送首字节数据丢失分析及解决方法

[复制链接]

1

主题

5

帖子

0

精华

初级会员

Rank: 2

积分
70
金钱
70
注册时间
2016-2-6
在线时间
19 小时
发表于 2016-2-29 14:05:29 | 显示全部楼层 |阅读模式
本帖最后由 qmcj 于 2016-3-1 12:25 编辑

现象:STM32 ZET6 硬件置位后,串口(USART)发送首字节数据丢;即硬件复位后,通过某个USART串口发送0x01、0x02、0x03,接收端只能接收到0x02、0x03,   0x01丢失;
原因分析:
                u8 USART_data[] = {0x01、0x02、0x03};

                for(t = 0; t < 3; t++)
                {                        
                        USART_SendData(USART2, USART_LCD1[t]);   //向串口2发送数据    语句A
                        while(USART_GetFlagStatus(USART2,USART_FLAG_TC)!=SET);   //等待发送结束    语句B
                }

根本原因:Status register (USART_SR)寄存器,复位初始化为0x00C0,正好TC(Transmission complete)标志位复位后是置1的,表示发送完毕;这样就会导致,当第一次执行语句A后,紧接着语句B也进行了执行,查询后发现TC=1(表示第一个字节已经发送完成),再次执行语句A,发送第二个字节,导致第一个字节在没有被发送时就被第二个字节所覆盖;其实可以看出,第一个TC=1是由硬件置位引起的,并不是第一个字节(0x01)真正发送完成所置位的;因此,第一个字节丢失;


需要特别注意的是:TC的清零规则,根据(STM32英文参考手册,P811)可知有两种方式:1 先读USART_SR寄存器,再写USART_DR寄存器;2 向TC位写0清TC;上述的代码就是采用了第一种方式清TC,即语句B是读USART_SR,语句A是写USART_DR寄存器;所以语句中并没有向TC位写0的语句;


解决“硬件置位,USART发送首字节丢失”方法:
1 在硬件置位后,语句A前,通过向TC位写0,来清TC位;即在语句A前加:USART_ClearFlag(USART2,USART_FLAG_TC);
2 在硬件置位后,语句A前,通过读取USART_SR寄存器以及后续的原有语句写USART_DR来清TC;即在语句A前加:USART_GetFlagStatus(USART2, USART_FLAG_TC);
3 语句A后给予短暂的时延,使得第一个字节真正被发送后,在进入循环发送(此方法其实有问题,不推荐)
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

30

主题

282

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1001
金钱
1001
注册时间
2015-8-24
在线时间
241 小时
发表于 2016-2-29 14:36:28 | 显示全部楼层
我是把语句B放在语句A的前面,就可以了。
回复 支持 反对

使用道具 举报

4

主题

98

帖子

0

精华

高级会员

Rank: 4

积分
755
金钱
755
注册时间
2015-9-16
在线时间
94 小时
发表于 2016-2-29 14:45:41 | 显示全部楼层
多谢分享
回复 支持 反对

使用道具 举报

354

主题

1475

帖子

12

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
8096
金钱
8096
注册时间
2015-10-15
在线时间
2919 小时
发表于 2016-2-29 14:49:06 | 显示全部楼层
谢谢楼主分享。。。谢谢
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
发表于 2016-2-29 15:18:10 | 显示全部楼层
Thank you for sharing.
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复 支持 反对

使用道具 举报

1

主题

5

帖子

0

精华

初级会员

Rank: 2

积分
70
金钱
70
注册时间
2016-2-6
在线时间
19 小时
 楼主| 发表于 2016-3-1 12:23:34 | 显示全部楼层
沉默焚烧 发表于 2016-2-29 14:36
我是把语句B放在语句A的前面,就可以了。

B放在A前面,那发送最后一个字节的时候,系统并没有等待发送完成,且没有清TC,从理论的角度是有风险的:)
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-20 23:34

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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