打印

DMA 接收溢出的问题

[复制链接]
5776|30
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
cb0035071|  楼主 | 2009-4-22 16:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
请教各位高手 如果DMA接收设置为4个字节,但发了5个字节时,会吧数组前面的字节覆盖掉,等下一次在发送4个字节的时候,DMA接收数组还是串了一个字节?怎么解决呢?
沙发
香水城| | 2009-4-22 16:16 | 只看该作者

什么芯片?

使用特权

评论回复
板凳
cb0035071|  楼主 | 2009-4-22 17:21 | 只看该作者

stm32103

stm32103

使用特权

评论回复
地板
香水城| | 2009-4-22 18:36 | 只看该作者

对方发送多于DMA设置的数目,多出的数据应该不会覆盖前面

除非你使用了DMA的循环模式。

多出的数据应该还在接收数据寄存器中,下次接收时,重新初始化一下接收通道即可。


你也真懒,使用的是什么接收通道都不说!

使用特权

评论回复
5
cb0035071|  楼主 | 2009-4-22 20:00 | 只看该作者

谢谢香主给我解答

谢谢香主给我解答
我用的DMA1_Chanel5 做的串口接收,循环模式和普通模式都试过了,重新初始化了,一旦有一次接收数据溢出,以后接收的数据都会错位

使用特权

评论回复
6
McuPlayer| | 2009-4-22 20:35 | 只看该作者

不要用环形缓冲区模式

使用特权

评论回复
7
cb0035071|  楼主 | 2009-4-22 20:57 | 只看该作者

用普通模式也覆盖

用普通模式也覆盖

使用特权

评论回复
8
cb0035071|  楼主 | 2009-4-22 22:19 | 只看该作者

用普通模式也覆盖

用普通模式也覆盖 

使用特权

评论回复
9
香水城| | 2009-4-23 07:47 | 只看该作者

用普通模式也覆盖?不大可能

仔细检查你的程序,操作、设置不当。

使用特权

评论回复
10
cb0035071|  楼主 | 2009-4-23 12:59 | 只看该作者

麻烦香主帮忙看下我的程序那出了问题

 RCC_Configuration();
       
  /* NVIC configuration */
  NVIC_Configuration();

  /* Configure the GPIO ports */
  GPIO_Configuration();

  /* Configure the DMA */
  //DMA_Configuration();
  

  /* DMA Channel4 (triggered by USART1 Tx event) Config */
  DMA_DeInit(DMA1_Channel4);
  DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)TxBuffer1;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  DMA_InitStructure.DMA_BufferSize = TxBufferSize1;
  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_VeryHigh;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel4, &DMA_InitStructure);

  DMA_DeInit(DMA1_Channel5);  
  DMA_InitStructure1.DMA_PeripheralBaseAddr = USART1_DR_Base;
  DMA_InitStructure1.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure1.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure1.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure1.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  DMA_InitStructure1.DMA_Mode = DMA_Mode_Normal;
  DMA_InitStructure1.DMA_Priority = DMA_Priority_VeryHigh;
  DMA_InitStructure1.DMA_M2M = DMA_M2M_Disable;
  DMA_InitStructure1.DMA_MemoryBaseAddr = (u32)&RxBuffer[0];
  DMA_InitStructure1.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure1.DMA_BufferSize = 4;
  DMA_Init(DMA1_Channel5, &DMA_InitStructure1);
 SetupUSART();
  /* Enable USART1 DMA TX request */
  USART_DMACmd(USART1, USART_DMAReq_Tx|USART_DMAReq_Rx, ENABLE);
  /* Enable DMA Channel5 Transfer Complete interrupt */
  DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);
  DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);
  /* Enable the USART1 Receive Interrupt */
  //USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

   /* Enable DMA Channel4 */
  //DMA_Cmd(DMA1_Channel4, ENABLE);
  /* Enable DMA Channel5 */
  DMA_Cmd(DMA1_Channel5, ENABLE);
 CurrDataCounter_End = DMA_GetCurrDataCounter(DMA1_Channel5);

  /* Wait until DMA_Channel 4 Transfer Complete */
  while(1)
  {
  ;        
  }

void DMAChannel5_IRQHandler(void)
{
if(DMA_GetITStatus(DMA1_IT_TC5))

        
        DMA_ClearITPendingBit(DMA1_IT_GL5);
        //CurrDataCounter_End = DMA_GetCurrDataCounter(DMA1_Channel5);
        DMA_Cmd(DMA1_Channel5, DISABLE);

        DMA_DeInit(DMA1_Channel5);  
       
        DMA_Init(DMA1_Channel5, &DMA_InitStructure1);

        /* Enable DMA Channel5 Transfer Complete interrupt */
        DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);
        DMA_Cmd(DMA1_Channel5, ENABLE);
        DMA_ClearITPendingBit(DMA1_IT_GL5);         
        dmaflag = 1;
        for(i=0;i<5;i++)
           RxBuffer1=0;

    }
}

使用特权

评论回复
11
cb0035071|  楼主 | 2009-4-23 14:23 | 只看该作者

香主帮忙看下,谢谢

香主帮忙看下,谢谢

使用特权

评论回复
12
香水城| | 2009-4-23 14:32 | 只看该作者

你在哪里重新初始化接收通道了?

请看我在4楼的说明:多出的数据应该还在接收数据寄存器中,下次接收时,重新初始化一下接收通道即可。

你怎么知道覆盖的数据不是上次通信多出来的?

使用特权

评论回复
13
cb0035071|  楼主 | 2009-4-23 14:43 | 只看该作者

进入DMA中断后初始化的

        DMA_DeInit(DMA1_Channel5);  
        DMA_Init(DMA1_Channel5, &DMA_InitStructure1);

        /* Enable DMA Channel5 Transfer Complete interrupt */
        DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);
        DMA_Cmd(DMA1_Channel5, ENABLE);
        DMA_ClearITPendingBit(DMA1_IT_GL5); 



        DMA_InitStructure1结构体没有重新付值因为我没有改变过结构体的值  

使用特权

评论回复
14
cb0035071|  楼主 | 2009-4-23 15:01 | 只看该作者

谢谢香主

DMA_Init(DMA1_Channel5, &DMA_InitStructure1);
这个函数是初始化接收通道吧,我测试了,是上次接收的数据覆盖了这次的数据,可是怎么把上次接收到的数据清掉呢

使用特权

评论回复
15
cb0035071|  楼主 | 2009-4-23 15:45 | 只看该作者

香主帮下忙

您看我初始化的对不对?

使用特权

评论回复
16
香水城| | 2009-4-23 15:50 | 只看该作者

请重新初始化你的通信通道,不是DMA通道

数据是从通信通道过来的,DMA通道没有数据!

使用特权

评论回复
17
cb0035071|  楼主 | 2009-4-23 16:11 | 只看该作者

串口1重新初始化了

串口1重新初始化了 也不行

使用特权

评论回复
18
cb0035071|  楼主 | 2009-4-24 08:14 | 只看该作者

没人遇到过类试的情况吗

没人遇到过类试的情况吗

使用特权

评论回复
19
香水城| | 2009-4-24 08:27 | 只看该作者

如何重新初始化UART1?

应该Disable,然后再Enable。


如果下次操作读到了上次多出的数据,说明重新初始化操作不对,重新初始化应能够把上次多出剩余在接收寄存器中的数据。重新初始化之后,接收缓冲器应该为空。

你也可以在DMA传输结束后,通过判断接收缓冲器是否为空,来判断对方是否多发了数据,如果对方确实多发了数据,也可以通过读出数据寄存器清除多出的数据。

使用特权

评论回复
20
cb0035071|  楼主 | 2009-4-24 09:22 | 只看该作者

是这么做的

是这么做的,先Disable,然后再Enable,在开启DMA后 出现接收乱的数据

使用特权

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

本版积分规则

5

主题

192

帖子

0

粉丝