打印

串口DMA发送的问题

[复制链接]
7098|28
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yyywill|  楼主 | 2010-8-20 12:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
u8 buf1[100]; //都初始化0
u8 buf2[100]; //都初始化0
u16 rev;   //中断接收计数
串口发送方式: DMA
串口接收方式: 中断

DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)buf1;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = 10;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize =DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel4, &DMA_InitStructure);

在主程序中
main()
while(1)
{
启动DMA发送;
延时;
}
是可以正常发送

而通过中断接收数据,再把接收的数据DMA发送出去就不对了,如下:
main()
while(1)
{
    if( rev > 10)
    {
        启动DMA发送;  //发送buf1
        rev = 0;
     }
}

串口接收中断中
u8 c;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{  
    c=USART1->DR;
    buf1[rev] = c;   //接收放在buf1
    rev ++;      
}  

当计算机这边发送11个字节数据时可以正常发回,当大于11个时,发回的就不是发出去的数据.
以为是buf1冲突

DMA_InitStructure.DMA_MemoryBaseAddr = (u32)buf2;
发送buf2的数据,怎么接收的也不是buf2里的数据.

最后把main里接收计数条件 换成 判断最后一个字节比如buf1[rev]=0x23
(PC端发送的数据中只有一个0x23,且是最后一个)
这样就正常,上面接收计数方法有问题吗,到底怎么回事
高手讲讲串口DMA注意的问题?
沙发
yyywill|  楼主 | 2010-8-20 14:45 | 只看该作者
牛人们都哪去了?

使用特权

评论回复
板凳
yyywill|  楼主 | 2010-8-21 10:56 | 只看该作者
大家都只看不想吗
还是STM用的人少?

使用特权

评论回复
地板
janeslee| | 2010-8-21 14:06 | 只看该作者
DMA过程中不能访问源内存,否则乱套了,你可以用BUF1和BUF2作为乒乓缓冲,BUF1接收的时候发送BUF2,循环往复。

使用特权

评论回复
5
香水城| | 2010-8-21 21:32 | 只看该作者
发送是需要时间的,当发送还没有结束时,如果接收到新的数据,会不会把没有发送的数据篡改了呢?

使用特权

评论回复
6
yyywill|  楼主 | 2010-8-22 10:23 | 只看该作者
DMA过程中不能访问源内存,否则乱套了,你可以用BUF1和BUF2作为乒乓缓冲,BUF1接收的时候发送BUF2,循环往复。
janeslee 发表于 2010-8-21 14:06


我上面说过,是有试过BUF1接收,DMA发送BUF2,而BUF2只在开始初始化,运行中不改变其中的数据,还是不对

感觉是不是同一串口在DMA发送的时候 不能再 中断 接收?

使用特权

评论回复
7
香水城| | 2010-8-22 10:47 | 只看该作者
我上面说过,是有试过BUF1接收,DMA发送BUF2,而BUF2只在开始初始化,运行中不改变其中的数据,还是不对

感觉是不是同一串口在DMA发送的时候 不能再 中断 接收? ...
yyywill 发表于 2010-8-22 10:23


不会有你说的这种情况。

你可以把试验的代码贴出来看看。

使用特权

评论回复
8
yyywill|  楼主 | 2010-8-22 10:51 | 只看该作者
实验代码 上面有啊,很简单

使用特权

评论回复
9
香水城| | 2010-8-22 11:06 | 只看该作者
如果能够正确处理10个字节,没有可能不能正确处理超过10个字节,请仔细确认在你改变字节数目时,所有的地方都作了相应的改变。

使用特权

评论回复
10
zgq605123| | 2010-8-22 11:07 | 只看该作者
我也在 听牛人解答

使用特权

评论回复
11
yyywill|  楼主 | 2010-8-22 11:25 | 只看该作者
如果能够正确处理10个字节,没有可能不能正确处理超过10个字节,请仔细确认在你改变字节数目时,所有的地方都作了相应的改变。
香水城 发表于 2010-8-22 11:06


当然了

发10字节时接收中断完成,DMA发送,正确
发10个以上字节时,在接收第10个字节时,DMA发送,这时第11个以后的字节来了,还会有接收中断产生,所以有
感觉是不是同一串口在DMA发送的时候 不能再 中断 接收?
如果说是BUF1冲突,我用DMA发送BUF2试了,也有问题

大家继续啊

使用特权

评论回复
12
香水城| | 2010-8-22 12:11 | 只看该作者
你还是好好地耐心的查查问题,不必用这么大的红字说你的感觉,前面不是说了吗,不会有你说的这种情况。

你用示波器看看,在有问题时,信号线上的波形是否与你看到的现象一致。

使用特权

评论回复
13
yyywill|  楼主 | 2010-8-23 11:35 | 只看该作者
本帖最后由 yyywill 于 2010-8-23 13:13 编辑
你还是好好地耐心的查查问题,不必用这么大的红字说你的感觉,前面不是说了吗,不会有你说的这种情况。

你用示波器看看,在有问题时,信号线上的波形是否与你看到的现象一致。 ...
香水城 发表于 2010-8-22 12:11


__IO uint8_t buf1[100];
__IO uint8_t buf2[100];
__IO uint8_t rev=0;


void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{  
     buf1[rev]=USART1->DR;
  rev++;      
}
}

void main(void)
{
    //初始化代码
    while(1)
   {
        //延时代码部分
        if(rev>10)
        {
            if(DMA_GetFlagStatus(DMA1_FLAG_TC4) != RESET)
            {
                DMA_Cmd(DMA1_Channel4, DISABLE);
                DMA_Configuration();
                USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
                DMA_Cmd(DMA1_Channel4, ENABLE);
            }
           rev = 0;
      }  
    }
}

实验得知:
main里延时代码,如果是大延时,是没有问题的.
很短的延时则会出问题。短延时,当我发送10个以上的字节都会出问题,不信你试试

还有:当把上面的串口1中断接收改成串口2中断接收,还是用BUF1,是没有任何问题的(很短的延时)

你说说是怎么回事?

使用特权

评论回复
14
香水城| | 2010-8-23 13:54 | 只看该作者
你的 if (rev > 10) 以下的代码只是启动了DMA的传输,如果在while循环了没有延时,则很有可能在DMA传输还没有结束时,程序又会进入启动DMA的部分,再次启动还未完成的DMA通道,这样当然会出错。

使用特权

评论回复
15
yyywill|  楼主 | 2010-8-23 14:08 | 只看该作者
本帖最后由 yyywill 于 2010-8-23 14:12 编辑
你的 if (rev > 10) 以下的代码只是启动了DMA的传输,如果在while循环了没有延时,则很有可能在DMA传输还没有结束时,程序又会进入启动DMA的部分,再次启动还未完成的DMA通道,这样当然会出错。 ...
香水城 发表于 2010-8-23 13:54


当把上面的串口1中断接收改成串口2中断接收,还是用BUF1,是没有任何问题的(很短的延时)

if (rev > 10)   马上就 rev=0了,我只发送了一次大于10字节的数据,因此是不可能DMA没有结束时,程序又会进入启动DMA的部分.(条件不满足)

最后,还是得出上面的结论:
同一串口在DMA发送的时候 不能再 中断 接收

使用特权

评论回复
16
香水城| | 2010-8-23 14:12 | 只看该作者
感觉是不是同一串口在DMA发送的时候 不能再 中断 接收
yyywill 发表于 2010-8-23 14:08


不是这样的!!

你是否总是凭感觉做事情呢?

使用特权

评论回复
17
香水城| | 2010-8-23 14:40 | 只看该作者
请把你的项目文件发上来,再详细描述一下测试方法,我们测试一下。

请说明你使用的芯片型号、调试和编译软件版本等信息。

使用特权

评论回复
18
yyywill|  楼主 | 2010-8-23 14:57 | 只看该作者
本帖最后由 yyywill 于 2010-8-23 15:02 编辑

芯片:STM32F103VC
MDK版本:4.11
IDE:uision4

PC端发送:01234567890   
再发送:012345678901 +

你试试

ST32F103VC_TEST.rar

321.51 KB, 阅读权限: 50

使用特权

评论回复
19
香水城| | 2010-8-23 17:48 | 只看该作者
测试过,没有问题。

使用特权

评论回复
20
yyywill|  楼主 | 2010-8-23 17:56 | 只看该作者
测试过,没有问题。
香水城 发表于 2010-8-23 17:48


我的DEMO里是串口2中断接收,你改成串口1中断接收测试没?

我无语了,难道是板子有问题?

使用特权

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

本版积分规则

7

主题

29

帖子

0

粉丝