12009|35

72

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

stm32的uart居然是单双工的 [复制链接]

本人刚开始学习stm32,从串口的例程开始。
看它介绍说是全双工的,实际一看就是单双工的嘛:因为共用一个寄存器来发送、接收,这样带来很大问题。
实际中,测试方法是:采用中断方式,将接收到的数据立即发送回去。
代码如下:
    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
    {
      // Read one byte from the receive data register 
      temp = USART_ReceiveData(USART2);      
      USART_SendData(USART2,temp);
      while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);
      {
            ;
      }
    }
实际中发现,每次发送一个字节给STM32的话,能正确执行。但是如果发送一串(用串口调试助手),则回来的全是乱码了。
再次测试,用一个数组将接收到的数据存起来,而不发送,则看到接收到的一串数据都是对的。
程序代码细节使用的是lib2.03的提供。
之前用过MSP430或LPC2xxx,做这样的程序都没有问题,这次stm32让人吃惊。请问这是我的程序问题还是stm32固有的?
此帖出自stm32/stm8论坛

最新回复

                                 U8 xBuffer[16];U32 pHead = 0;U32 pEnd = 0;while(1){  if(USART_GetITStatus(USART2, USART_FLAG_RXNE) != RESET)  {      xBuffer[pEnd++] = USART_ReceiveData(USART2);       pEnd &= 0x0f;       }     if((pHead != pEnd)&&(USART_GetFlagStatus(USART2, USART_FLAG_TXE) != RESET))  {           USART_SendData(USART2, xBuffer[pHead++]);       pHead &= 0x0f;  }}   详情 回复 发表于 2009-5-27 11:56
点赞 关注
 

回复
举报

71

帖子

0

TA的资源

一粒金砂(初级)

沙发
 

自己的问题! 晕!!

                                  
此帖出自stm32/stm8论坛
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

板凳
 

你下结论也太草率了吧?

请注意发送和接收使用不同的寄存器,但操作的名字是一样的。

看看这个USART的框图:
此帖出自stm32/stm8论坛
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

4
 

那怎么解释我这个现象呢?

那怎么解释我这个现象呢?
接单个字节能转发正常,接一串就不行(比如发23字节,可能收23或更少字节回来,但数据基本不对)。接一串数据时,如果不转发回来而放在数组里缓存,也是正常的。
我的主函数就是while(1){ ;}。

----这直观的理解就是,转发刚收到的字节时占用了过长的时间,以至于不能正常接收下一个字节。
此帖出自stm32/stm8论坛
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

5
 

好好看看你的程序吧

比如这一句话:
while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);

这意味着发送不结束,不会进入循环的下一个周期接收新的数据。如果发送方连续无间隔地发送数据,你的程序肯定出错!
此帖出自stm32/stm8论坛
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

6
 

谢谢,你说的我能理解

                                 但是,比stm32慢很多的msp430执行这样的函数都不会出错,更不要说lpc2xxx了,为什么stm32搞不定呢?难道非要利用发送中断再加一个定时器才能完成串口转发的工作吗?
此帖出自stm32/stm8论坛
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

7
 

还有,stm32没有串口超时中断、没有FIFO感觉有点遗憾

                                 之前用LPC2xxx的,有串口超时中断、带FIFO这几点感觉很好,stm32没有,虽然说可以通过其它途径也能实现同样的功能,但还是觉得有点点遗憾
此帖出自stm32/stm8论坛
 
 
 

回复

57

帖子

0

TA的资源

一粒金砂(初级)

8
 

请问你的通讯波特率是多少?

                                 个人感觉是你的程序整体流程存在问题,但是看不到全部代码,无法判别。
此帖出自stm32/stm8论坛
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(初级)

9
 

你并没有理解我的意思

这是你的程序,我把它编上行号:
1    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
2    {
3      // Read one byte from the receive data register 
4      temp = USART_ReceiveData(USART2);      
5      USART_SendData(USART2,temp);
6      while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);
7      {
8            ;
9      }
10    }

当收到一个字节后,即收到一个字节的停止位后,才有RXNE标志,也就是说程序进入到第4行时,肯定是在停止位之后,至于离停止位有多远,需要看程序的第1行离停止位有多远。

程序从第4行进入到第10行时,意味着你发送的一个字节的停止位已经发送完毕。

你是否看到,在接收到一个字节的停止位到发送出同样字节的停止位,这个时间间隔大于线路上传送一个字节的长度,这正是我前面说的“如果发送方连续无间隔地发送数据,你的程序肯定出错!”


其实你的问题很简单,因为发送和接收的速率是一样的,只要去掉第6~9行的代码即可,何必搞那么复杂。
此帖出自stm32/stm8论坛
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

10
 

我做了实验

谢谢各位讨论!
刚做了一下实验:
1 和波特率没有关系,9600 115200都会有问题;
2 浪淘沙,你所提到的“只要去掉第6~9行的代码即可,何必搞那么复杂。”实验发现是不行的,这样做的结果就只有字符串中最后一个字 偶尔 能能正确发出去。
你刚才提到说“while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);”这句话会阻碍接收后面的一个字节,但是那接收到的第一个字节应该能正确转发回去吧,但事实是第一个字节也不能正确转发回去。

我这个程序就是改自 lib库下的 ExamplesUSARTInterrupt 下的,如果哪位有兴趣,也做一下实验看看好吗?
谢谢
此帖出自stm32/stm8论坛
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

11
 

还是把你改过的程序贴出来吧

                                 别人改了以后即使没有问题,你的程序哪里错了你还是不知道。
此帖出自stm32/stm8论坛
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

12
 

是不是你的程序与原来的中断程序冲突了?

                                  
此帖出自stm32/stm8论坛
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

13
 

串行通信这么慢的通信方式

绝大部分场合应该选择中断来驱动

和单条指令的执行周期相比,串行发送完一个字节要消耗相当长的时间。
此帖出自stm32/stm8论坛
 
 
 

回复

67

帖子

0

TA的资源

一粒金砂(初级)

14
 

程序见附件

我用的深圳英倍特公司的STM32E开发板,上面芯片是STM32F103ZET6,Z版本。
keil用的3.40.

因为一次发送单个字节总能正确转发回来,而且一次发送多个字节也能有返回,所以香版说的 “是不是你的程序与原来的中断程序冲突了?”应该可以排除。

谢谢大家讨论
相关链接:https://bbs.eeworld.com.cn/upfiles/img/20095/200951816646853.rar
此帖出自stm32/stm8论坛
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

15
 

初生牛犊有冲劲……

                                  
此帖出自stm32/stm8论坛
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

16
 

2.34MB,你的程序怎么这么大,让人怎么看?

                                  
此帖出自stm32/stm8论坛
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

17
 

大部分都是keil生成的.o,.crf文件

因为我把lib以c文件形式加进去的,大部分都是keil生成的.o,.crf文件,我这里修改的就是main.c和stm32f10x_it.c两个文件而已。
请注意,我用的是uart2,如果是用uart1的话,丢数据情况会好一点,但还是会丢,比如23个字节会丢2个。

我觉得,如果能排除是我程序的问题(但实际我就是用的lib中的例子)的话,那就证明了 1 uart是单双工 或者 2 把中断向量表放在flash里会引起中断处理很慢(我这里用的例子,中断向量放在flash里)

正是因为有可能是这两个问题,所以我才追究了一下,而不是  mohanwei 兄所谓的 “初生牛犊有冲劲……”

期待哪位的实验结果
此帖出自stm32/stm8论坛
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

18
 

说一下个人的看法

CPU设计出来是要让正常用起来,而不是任何方法都可以用的;
其实串口发送接收不是很复杂,可能是楼主的想法比较别致;
1.串口可以全双工,如果是全双工,最好采用中断方式接收发,否则可能会造成数据丢失;
2.CPU只有一个,就是说实际执行的只有一条线,由于没有FIFO,所以不用中断的话,处理不好就会...丢数据的
此帖出自stm32/stm8论坛
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

19
 

猜一下

  之前用过MSP430或LPC2xxx,做这样的程序都没有问题,这次stm32让人吃惊。请问这是我的程序问题还是stm32固有的?
  猜一下:
因为MSP430或LPC2xxx的串口有FIFO,而STM32的串口没有FIFO
此帖出自stm32/stm8论坛
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

20
 

我觉得和FIFO有一定关系,但不大

我这么做并不是应用所要求,只是学习串口程序设计时这么测试来着

我觉得和FIFO有一定关系,但不大,否者不好解释 转发一个字节正确的现象,也不好解释转发一串字节时连第一个字节都出错的现象
此帖出自stm32/stm8论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表