打印

stm32的uart居然是单双工的

[复制链接]
17910|39
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
skyhigh|  楼主 | 2009-5-18 13:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本人刚开始学习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固有的?
沙发
aaron238| | 2009-5-18 13:42 | 只看该作者

自己的问题! 晕!!

使用特权

评论回复
板凳
浪淘沙| | 2009-5-18 14:05 | 只看该作者

你下结论也太草率了吧?

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

看看这个USART的框图:

使用特权

评论回复
地板
skyhigh|  楼主 | 2009-5-18 14:18 | 只看该作者

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

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

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

使用特权

评论回复
5
浪淘沙| | 2009-5-18 14:22 | 只看该作者

好好看看你的程序吧

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

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

使用特权

评论回复
6
skyhigh|  楼主 | 2009-5-18 14:43 | 只看该作者

谢谢,你说的我能理解

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

使用特权

评论回复
7
skyhigh|  楼主 | 2009-5-18 14:46 | 只看该作者

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

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

使用特权

评论回复
8
ST_ARM| | 2009-5-18 15:00 | 只看该作者

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

个人感觉是你的程序整体流程存在问题,但是看不到全部代码,无法判别。

使用特权

评论回复
9
浪淘沙| | 2009-5-18 15:06 | 只看该作者

你并没有理解我的意思

这是你的程序,我把它编上行号:
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行的代码即可,何必搞那么复杂。

使用特权

评论回复
10
skyhigh|  楼主 | 2009-5-18 15:46 | 只看该作者

我做了实验

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

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

使用特权

评论回复
11
浪淘沙| | 2009-5-18 15:51 | 只看该作者

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

别人改了以后即使没有问题,你的程序哪里错了你还是不知道。

使用特权

评论回复
12
香水城| | 2009-5-18 15:54 | 只看该作者

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

使用特权

评论回复
13
john_light| | 2009-5-18 15:57 | 只看该作者

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

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

和单条指令的执行周期相比,串行发送完一个字节要消耗相当长的时间。

使用特权

评论回复
14
skyhigh|  楼主 | 2009-5-18 16:11 | 只看该作者

程序见附件

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

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

谢谢大家讨论
相关链接:https://bbs.21ic.com/upfiles/img/20095/200951816646853.rar

使用特权

评论回复
15
mohanwei| | 2009-5-18 16:18 | 只看该作者

初生牛犊有冲劲……

使用特权

评论回复
16
浪淘沙| | 2009-5-18 16:37 | 只看该作者

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

使用特权

评论回复
17
skyhigh|  楼主 | 2009-5-18 16:51 | 只看该作者

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

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

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

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

期待哪位的实验结果

使用特权

评论回复
18
ningzb| | 2009-5-18 17:04 | 只看该作者

说一下个人的看法

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

使用特权

评论回复
19
ijk| | 2009-5-18 17:04 | 只看该作者

猜一下

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

使用特权

评论回复
20
skyhigh|  楼主 | 2009-5-18 17:13 | 只看该作者

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

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

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

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

29

帖子

1

粉丝