OpenEdv-开源电子网

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

STM32F103系列USART的发送完成标志TC的疑惑

[复制链接]

15

主题

50

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
322
金钱
322
注册时间
2014-10-29
在线时间
37 小时
发表于 2015-8-24 12:37:04 | 显示全部楼层 |阅读模式
大家好,近期工作需要用到USART的通信,我参考了原子哥的串口程序,接着有分析了datasheet,个人感觉原子哥的串口例程有点小问题。接下来说下自己的理由,不正确的,还请大家帮忙分析!
1. 按照原子哥的串口例程,初始化后,发送完成标志位TC已经是置1的,这和数据手册上说的一样,并且初始化只开启了接收中断。对TC为并无做任何处理。


2. 在主函数中,根据接收数据的长度,进行for循环回显,for循环里面每次发送一个字节,就while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束   ,我觉得这里是不是没有起到判断的作用,因为不管你把数据放到DR后,或是有DR移到移位寄存器并由TX发送出去的过程中TC位一直都是 1 。如果数据在发送过程中出现问题,我们怎样根据TC位来判断,数据是否真的正确发送完成。


3.所以我在想,这里是否需要启用发送完成TC的中断,进行判断。
   以上是自己的理解,现在还有点迷茫,希望会的朋友给予帮助,说明一下,我现在使用的开发板例程是战舰V2.2配套的,不知道新版的例程有没有更新,谢谢大家!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

239

帖子

0

精华

高级会员

Rank: 4

积分
545
金钱
545
注册时间
2015-6-5
在线时间
110 小时
发表于 2015-8-24 13:18:58 | 显示全部楼层
回复 支持 反对

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
发表于 2015-8-24 13:23:54 | 显示全部楼层


1.读完寄存器再写入数据会清0一次,然后发送完成后才会置一
2.楼主用的什么截图软件么?求推荐。截图真清楚,这帖子整体看起来挺好看的,赞一个
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复 支持 反对

使用道具 举报

15

主题

50

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
322
金钱
322
注册时间
2014-10-29
在线时间
37 小时
 楼主| 发表于 2015-8-24 13:24:36 | 显示全部楼层
我有看了一下程序和数据手册,是不是可以这样理解:当TC置1后,清除的方法是   “由软件序列清除该位(先读USART_SR,然后写入USART_DR)。”   那么在主函数中的for循环中有读USART_SR寄存器的操作(while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);) ,然后等下一个for到来后,将下一个字节放入DR中。但是顺序是不是没有按照“先读USART_SR,然后写入USART_DR”来清除TC位,例如:发送第一个数据时(再将数据放入DR之前TC已经为1)将数据放入DR后,发送等待TC=1(while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET)),好、此时判断成立,那么下一个for循环时我们的操作是先将数据放入DR,后判断读的USART_SR,这样是不是没有起到清除TC位的目的(此时TC是否仍然是1)?     总之我现在的迷茫点在于:既然我们使用TC判断发送完成,那么一开始TC就是1,怎样用,还有在发送的哪个过程TC被清为0,如果没有被清0,那么这样判断是不是有缺陷?  谢谢!
回复 支持 反对

使用道具 举报

15

主题

50

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
322
金钱
322
注册时间
2014-10-29
在线时间
37 小时
 楼主| 发表于 2015-8-24 13:32:08 | 显示全部楼层
回复【3楼】龙之谷:
---------------------------------
呵呵  我明白了  原子哥的例程可以这样理解:当我们发送第一个数据时,TC已经置1,那么在我们第一个for循环后,类似于操作了(“先读USART_SR,“),此时TC还是1,然后在第二个for中,首先写了一下USART_DR,(此时TC已经被清零了,因为满足了“由软件序列清除该位(先读USART_SR,然后写入USART_DR)。”),接着等待TC的再次置1,依次循环,那么这样是不是会对第一个数据起不到判断发送完成的作用,是不是应该在初始化中对TC位坐下处理?
回复 支持 反对

使用道具 举报

15

主题

50

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
322
金钱
322
注册时间
2014-10-29
在线时间
37 小时
 楼主| 发表于 2015-8-24 13:34:57 | 显示全部楼层
回复【2楼】Rocks:
---------------------------------
复位后为1,数据从TX脚上发送完成后为1,   你什么时候按照手册的方法把TC清零了(由软件序列清除该位(先读USART_SR,然后写入USART_DR)。 TC
位也可以通过写入’0’来清除,只有在多缓存通讯中才推荐这种清除程序。)   为0
回复 支持 反对

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
发表于 2015-8-24 14:01:43 | 显示全部楼层



while语句已经做了处理了,不知道库函数是不是一样做法
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复 支持 反对

使用道具 举报

15

主题

50

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
322
金钱
322
注册时间
2014-10-29
在线时间
37 小时
 楼主| 发表于 2015-8-24 14:28:36 | 显示全部楼层
回复【7楼】龙之谷:
---------------------------------
回复【7楼】龙之谷:
---------------------------------
你的意思是这段代码是在初始化里出现的,就是说这里”while(*******)“;就可以在开始发送数据前将TC清0吗?这里貌似是等待TC为1吧,否则程序就停这里了。
回复 支持 反对

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
发表于 2015-8-24 14:45:55 | 显示全部楼层
回复【8楼】互利共赢:
---------------------------------
完成清零需要哪两步

1.读SR寄存器;2.写DR寄存器

这里完成读,后边for循环开始完成写,这个过程不就是你要的对第一个数的清零后等待发送完成的过程吗
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复 支持 反对

使用道具 举报

15

主题

50

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
322
金钱
322
注册时间
2014-10-29
在线时间
37 小时
 楼主| 发表于 2015-8-24 15:05:26 | 显示全部楼层
回复【9楼】龙之谷:
---------------------------------
呵呵  是的  这样就对了,这次算是明白了,谢谢啊!对了,你那边的例程是新版的吧,我看了下我这边寄存器版的例程,没有加这样的处理。
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-16 06:20

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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