打印

我的Usart3接收也僵住了

[复制链接]
4290|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tsx1983|  楼主 | 2008-12-19 10:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我用DMA发送和接收,如果设定Usart3接收30字节,我要连续给他发送超过30个字节,下次我再设定接收的时候无论如何都再也一个字节都接收不了了,查看各个DMA和串口相关寄存器的状态也都是打开的。但是发送依然是正常的。如果我每次接收完之后再延时一段时间等待后续的字节发送完毕后再发送的话就正常,就是说使用DMA传输一定要等到接收线上没有字节接收的时候我再发送才能正常工作,如果在接收的同时我用DMA发送,似乎接收立刻就永远的僵住了。
请问香主,利用DMA传输是不是不能够同时收发 ?
沙发
香水城| | 2008-12-19 10:51 | 只看该作者

对不起,你的描述太饶舌了,请说明是谁在发送谁在接收?

比如这句话“每次接收完之后再延时一段时间等待后续的字节发送完毕后再发送的话就正常”,还有其它说明,实在看不明白。

最好能用1、2、3、4,条理清晰地描述流程。

使用特权

评论回复
板凳
tsx1983|  楼主 | 2008-12-19 11:57 | 只看该作者

我晕,再来一次吧

1.如果我设定STM32接收30字节,但是我的上位机软件给它连续发了超过30字节的数据,STM32接收完30字节后立刻应答。第一次能成功接收并应答,但是接着第二次就什么也收不到了。

2.如果我设定STM32接收30字节,上位机软件连续发送超过30字节时,STM32接收完30字节后延时一段时间,再来应答上位机,一切正常,下次接收的时候依然能正常接收

3.总之言之就是上位机往下发送的同时我不能应答,一旦应答,串口的接收就彻底死了,再也收不到了。但是发送还是正常的。

使用特权

评论回复
地板
香水城| | 2008-12-19 12:17 | 只看该作者

请检查错误标志位,估计你没有正确地处理错误标志

你这种情况会造成接收缓冲区溢出,如果不正确处理则操作会不正常。

使用特权

评论回复
5
tsx1983|  楼主 | 2008-12-19 17:18 | 只看该作者

发现确实是错误标志置位了,但是

用LCD显示了一下接收完成后的错误状态,有时候USART_FLAG_ORE=SET了。
但是为何我清都清不掉呢。
代码是每次接收完毕和开始接收都把下面四个错误标志
USART_FLAG_ORE,USART_FLAG_NE,USART_FLAG_FE,USART_FLAG_PE清除了,
但清除后发现USART_GetFlagStatus(USART3,USART_FLAG_ORE)还是等于SET。

使用特权

评论回复
6
香水城| | 2008-12-19 17:23 | 只看该作者

你是如何清除这些标志的?

只有在读USART_SR寄存器之后再读USART_DR才能清除它们,这些标志位为只读位,不能直接清除。

使用特权

评论回复
7
tsx1983|  楼主 | 2008-12-19 17:33 | 只看该作者

我调用库函数的

if(USART_GetFlagStatus(USART3,USART_FLAG_ORE)==SET)
    {
       GUI_DispStringAt("USART_FLAG_ORE==SET  ",4,4);
       USART_ClearFlag(USART3,USART_FLAG_ORE); 
    }
现在有这种现象,我先打开上位机软件,再按STM32的复位键,能通讯成功 一次,一次之后USART_FLAG_ORE就是SET了,而且一直是这样,清不掉。

我要先把STM32复位了,再打开上位机软件,通讯能连续成功很多次,具体多少次每次都不一样。但是通到一定的时候USART_FLAG_ORE还是会被SET。一旦SET之后就在也清不掉了

使用特权

评论回复
8
香水城| | 2008-12-19 18:23 | 只看该作者

这个函数不是用来清除错误标志的

正如我在7楼讲的:“只有在读USART_SR寄存器之后再读USART_DR才能清除它们,这些标志位为只读位,不能直接清除”,而这个函数恰恰是做直接清除的动作。

实际上,if(USART_GetFlagStatus(USART3,USART_FLAG_ORE)==SET)隐含着读USART_SR寄存器;你必须在检测到这个错误标志后,再读一次USART_DR,比如这样的语句:temp = USART3->DR;

如果你不关心这些错误标志,而又想在下次使用USART时清除所有的错误标志,最好的办法是执行一次USART的复位操作,然后再重新设置(初始化)一下这个USART,这样的效果与你复位整个芯片是一样的,不同的是只有指定的USART受到影响。执行一次USART3的复位操作是这样的:
  RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, DISABLE); // 复位
  RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, ENABLE); // 结束复位

使用特权

评论回复
9
tsx1983|  楼主 | 2008-12-20 14:10 | 只看该作者

感谢香主

一会写程序测测。我用的DMA传输,感觉要是上位机正在往STM32发送数据的话,这是打开串口,它就会被SET,然后就回不来了。今天早上看了一遍数据手册,数据手册上说要在DMA的中断里将DMA允许位清除掉。

使用特权

评论回复
10
tsx1983|  楼主 | 2008-12-20 17:39 | 只看该作者

问题解决

仔细看了下函数库,发现注释的底下有句话我没注意,就是调用USART_ClearFlag(USART3,USART_FLAG_ORE); 函数后要读USART3->DR才能清除USART_FLAG_ORE标志位

使用特权

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

本版积分规则

25

主题

160

帖子

0

粉丝