发新帖我要提问
12
返回列表
打印

DMA 接收溢出的问题

[复制链接]
楼主: cb0035071
手机看帖
扫描二维码
随时随地手机跟帖
21
vigia| | 2009-4-24 09:39 | 只看该作者 回帖奖励 |倒序浏览

看看我的代码

启动DMA
  DMA_Channel4_CNDTR = xxx;         // initiate the length of the dma channel4
  DMA_Channel5_CNDTR = xxx;           //initiate the length of the dma channel5
  DMA_Channel4_CMAR = (u32)xxx;         // initiate the memory address of the dma channel4
  DMA_Channel5_CMAR = (u32)xxx;      // initiate the memory address of the dma channel5
  DMA_Channel4_CCR |= CCR_ENABLE_Set;                     // enable dma chennel4
  DMA_Channel5_CCR |= CCR_ENABLE_Set;                     // enable dma chennel5  
  USART1->CR3 |= (u16)(USART_DMAReq_Rx | USART_DMAReq_Tx);  // enable usart1 send/receive dma request
  USART1->CR1 |= CR1_UE_Set;                                // enable usart1
  
关闭DMA

USART1->CR3 &= (u16)~(USART_DMAReq_Rx | USART_DMAReq_Tx); // disable usart1 send/receive dma request
DMA_Channel4_CCR &= CCR_ENABLE_Reset;                   // disable dma chanel4
DMA_Channel5_CCR &= CCR_ENABLE_Reset;                   // disable dma chanel5  
USART1->CR1 &=CR1_UE_Reset;                             // disable USART1  

按照以上顺序试试。

使用特权

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

香主请看下我程序


/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_lib.h"

/* Private typedef -----------------------------------------------------------*/
typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;

/* Private define ------------------------------------------------------------*/
#define USART1_DR_Base  0x40013804
#define USART2_DR_Base  0x40004404
#define TxBufferSize1   (countof(TxBuffer1) - 1)
#define TxBufferSize2   (countof(TxBuffer2) - 1)

/* Private macro -------------------------------------------------------------*/
#define countof(a)   (sizeof(a) / sizeof(*(a)))

/* Private variables ---------------------------------------------------------*/
USART_InitTypeDef USART_InitStructure;
u8 TxBuffer1[] = "123456789";
u8 TxBuffer2[] = "USART Example 6: USART2 -> USART1 using DMA Tx and Rx Interrupt";

u8 RxBuffer1[TxBufferSize2];
u8 RxBuffer2[TxBufferSize1];
u8 RxBuffer[4];

u8 NbrOfDataToRead = TxBufferSize1;
u8 index = 0,dmaflag=0,i;
u16 CurrDataCounter_End = 0,CurrDataCounter_End1,err,err1,err2,err3;
volatile TestStatus TransferStatus1 = FAILED, TransferStatus2 = FAILED;  
ErrorStatus HSEStartUpStatus1;
DMA_InitTypeDef DMA_InitStructure,DMA_InitStructure1;
/* Private function prototypes -----------------------------------------------*/
extern void SetupUSART(void); 
extern  int GetKey (void) ;
extern  void delay (int cnt)  ;
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void DMA_Configuration(void);
TestStatus Buffercmp(u8* pBuffer1, u8* pBuffer2, u16 BufferLength);

int main(void)
{
#ifdef DEBUG
  debug();
#endif
 
  /* System Clocks Configuration */
  RCC_Configuration();
       
  /* NVIC configuration */
  NVIC_Configuration();

  /* Configure the GPIO ports */
  GPIO_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;
  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)
  {
          if(dmaflag == 1)    
        {
            /*USART_Cmd(USART1, DISABLE);
            delay(100);
            DMA_Cmd(DMA1_Channel5, ENABLE);
            DMA_ClearITPendingBit(DMA1_IT_GL5);
            USART_Cmd(USART1, ENABLE);    
            if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==1)
            GetKey();
            dmaflag =0;*/
            index = 9;
        }
  }
}
void DMAChannel5_IRQHandler(void)
{
    if(DMA_GetITStatus(DMA1_IT_TC5))
    {  
    
        DMA_ClearITPendingBit(DMA1_IT_GL5);
        CurrDataCounter_End = DMA_GetCurrDataCounter(DMA1_Channel5);

        USART_Cmd(USART1, DISABLE);    
        USART_Cmd(USART1, ENABLE);

          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;
          DMA_InitStructure1.DMA_DIR = DMA_DIR_PeripheralSRC;
          DMA_InitStructure1.DMA_BufferSize = 4;
          DMA_Init(DMA1_Channel5, &DMA_InitStructure1);
        /*USART_DeInit(USART1);
        SetupUSART();
        USART_ClearFlag(USART1, USART_FLAG_RXNE);*/  
          USART_DMACmd(USART1, USART_DMAReq_Tx|USART_DMAReq_Rx, ENABLE);;
        DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);    
        
        if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==1)
        GetKey();
        DMA_Cmd(DMA1_Channel5, ENABLE);
        DMA_ClearITPendingBit(DMA1_IT_GL5);
                 
        dmaflag =1;
        for(i=0;i<5;i++)
           RxBuffer1=0;

    }
}

使用特权

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

按照vigia大侠的顺序试过了,也不行

按照vigia大侠的顺序试过了,也不行

使用特权

评论回复
24
香水城| | 2009-4-24 10:21 | 只看该作者

Disable -> 初始化 -> Enable

使用特权

评论回复
25
cb0035071|  楼主 | 2009-4-24 10:33 | 只看该作者

初始化串口 出现乱数

初始化串口 出现乱数

使用特权

评论回复
26
香水城| | 2009-4-24 10:49 | 只看该作者

实际上你只需要在下次接收之前检测是否有多余的数据,再

你再仔细地看看程序,运行中在再次开始接收前看看各个寄存器的状态,问题应该不难解决,我不知道你为什么越搞越复杂。


比如22楼贴出的程序最后:

        USART_DMACmd(USART1, USART_DMAReq_Tx|USART_DMAReq_Rx, ENABLE);;
        DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);    
        
        if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==1)
        GetKey();
        DMA_Cmd(DMA1_Channel5, ENABLE);
        DMA_ClearITPendingBit(DMA1_IT_GL5);
                 
        dmaflag =1;
        for(i=0;i<5;i++)
           RxBuffer1=0;

不知道你为什么要先打开DMA通道,再去判断USART_FLAG_RXNE?
然后又在使能了DMA通道后,清除所有接收寄存器,如果这时已经有数据进来,不是又被你清除了吗?

使用特权

评论回复
27
cb0035071|  楼主 | 2009-4-24 10:54 | 只看该作者

各种顺序都试过,都不好用

各种排列组合的顺序都试过,都不好用,不清除也试过,但不好使啊,刚才问个代理商,他们说这种情况在硬件初始化上没办法解决,只能在软件上解决

使用特权

评论回复
28
zcw9911| | 2009-4-24 17:04 | 只看该作者

我的办法是缓冲区开大一些

然后定时检查DMA的字节数来判断接收是否完成,这种暂时还没有发现问题

使用特权

评论回复
29
cjf512| | 2009-4-25 09:31 | 只看该作者

DMA接收的Buffer 也需要初始化,因为你在递增的。

使用特权

评论回复
30
香水城| | 2009-4-25 09:47 | 只看该作者

请看看21楼的方式

1)关闭DMA和USART1

USART1->CR3 &= (u16)~(USART_DMAReq_Rx | USART_DMAReq_Tx); // disable usart1 send/receive dma request
DMA_Channel4_CCR &= CCR_ENABLE_Reset;                   // disable dma chanel4
DMA_Channel5_CCR &= CCR_ENABLE_Reset;                   // disable dma chanel5  
USART1->CR1 &=CR1_UE_Reset;                             // disable USART1  

2)初始化USART1

3)启动DMA和USART1


  DMA_Channel4_CNDTR = xxx;         // initiate the length of the dma channel4
  DMA_Channel5_CNDTR = xxx;           //initiate the length of the dma channel5
  DMA_Channel4_CMAR = (u32)xxx;         // initiate the memory address of the dma channel4
  DMA_Channel5_CMAR = (u32)xxx;      // initiate the memory address of the dma channel5
  DMA_Channel4_CCR |= CCR_ENABLE_Set;                     // enable dma chennel4
  DMA_Channel5_CCR |= CCR_ENABLE_Set;                     // enable dma chennel5  
  USART1->CR3 |= (u16)(USART_DMAReq_Rx | USART_DMAReq_Tx);  // enable usart1 send/receive dma request
  USART1->CR1 |= CR1_UE_Set;                                // enable usart1

使用特权

评论回复
31
humanking7| | 2013-3-6 18:00 | 只看该作者
cb0035071 发表于 2009-4-24 09:22
是这么做的,先Disable,然后再Enable,在开启DMA后&nbsp;出现接收乱的数据

您的这个问题解决了吗,我也出现了这个问题,https://bbs.21ic.com/icview-447465-1-1.html,如果少发了数据,比如说你的定义是4个,先发了3个,然后在发4个,这样也会暴露出问题,我现在就无法玩耍了,困扰了好几天了,dma串口接收问题,求破

使用特权

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

本版积分规则