初级会员 
  
	- 积分
 - 54
 
        - 金钱
 - 54 
 
       - 注册时间
 - 2016-10-12
 
      - 在线时间
 - 14 小时
 
 
 
 | 
 
10金钱 
求教!在写STM32F405 DMA+空闲中断接收,用的是USART3,看了网上很多分享的帖子了,但是都不行,出现的现象是: 
1)我设置的BufferSize是16,必须要满足16个数后,才能触发我的空闲中断,且继续发送数据,偶尔会触发中断,但是接收DMA可正常工作,但是DMA_GetCurrDataCounter(DMA1_Stream1)与实际发送数据不符! 
2)调整配置顺序,如先使能DMA,再配置USART,每次可以进中断,但是DMA不接收数据,接收寄存器一直为0,DR寄存器里显示是我发的一帧数据的第一个; 
我的源程序如下,请帮我找找原因,我已经调了很多天了,但是这个一直困扰我!谢谢谢谢谢谢! 
void USART3_Configuration(void)    // 串口配置函数 
 {  
   GPIO_InitTypeDef GPIO_InitStructure;       
   NVIC_InitTypeDef NVIC_InitStructure; 
   USART_InitTypeDef USART_InitStructure;   
 
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE); //使能GPIOC时钟  
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);//使能USART3时钟,挂在APB1上 
 
    GPIO_PinAFConfig(GPIOC,GPIO_PinSource10,GPIO_AF_USART3); //GPIOC10复用USART3_TX 
    GPIO_PinAFConfig(GPIOC,GPIO_PinSource11,GPIO_AF_USART3); //GPIOC11复用USART3_RX  
 //发送TXPIN   
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;   
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;   
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;   
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
     GPIO_Init(GPIOC, &GPIO_InitStructure);   
 //接收RXPIN   
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;   
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;   
     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //上拉    
     GPIO_Init(GPIOC, &GPIO_InitStructure); 
 
    USART_InitStructure.USART_BaudRate = 115200;//波特率设置 
 
   USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式 
   USART_InitStructure.USART_StopBits = USART_StopBits_1;//1个停止位 
   USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位 
   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制 
   USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //收发模式 
   USART_Init(USART3, &USART_InitStructure); //初始化串口3 
   USART_ITConfig(USART3, USART_IT_IDLE, ENABLE); 
   USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE);  
 
  NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; //串口3中断通道 
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级2 
  NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;  //子优先级0 
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;   //IRQ通道使能 
  NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器 
  USART_Cmd(USART3, ENABLE);  //使能串口3 
} 
 
void DMA_Usart_Init() 
 { 
  DMA_InitTypeDef DMA_InitStructure; 
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); // 开启DMA1时钟  
DMA_InitStructure.DMA_Channel =  DMA_Channel_4;    //外设的接收通道 
  DMA_InitStructure.DMA_PeripheralBaseAddr =  (int32_t)&USART3->DR; //source  buf 
  DMA_InitStructure.DMA_Memory0BaseAddr = (int32_t)&USART3_R_BUF; //target buf 
  DMA_InitStructure.DMA_DIR =  DMA_DIR_PeripheralToMemory;  //外设寄存器 -> 内存缓冲区? 
  DMA_InitStructure.DMA_BufferSize = 18;  //BuffSize; 
  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_Circular;//DMA_Mode_Circular;  //DMA_Mode_Normal; //接收设计为循环收,否则接收一次后,无法正常接收到数据 
  DMA_InitStructure.DMA_Priority = DMA_Priority_High; 
   
  DMA_InitStructure.DMA_FIFOMode =  DMA_FIFOMode_Disable; 
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; //指定FIFO阈值水平 
//  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; 
  DMA_InitStructure.DMA_MemoryBurst =  DMA_MemoryBurst_Single;// DMA_MemoryBurst_Single;      //指定Burst转移配置内存传输,单次传输 
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; // 指定的burst转移配置外围转移 
   
  DMA_Init(DMA1_Stream1,  &DMA_InitStructure); 
  DMA_Cmd(DMA1_Stream1, ENABLE); 
} 
 
 void USART3_IRQHandler(void)  
{ 
 
      uint32_t temp = 0;   
       uint16_t i = 0;  
       unsigned char r = 0;     
 if((USART_GetFlagStatus(USART3,USART_IT_IDLE)) != RESET) 
  { 
   DMA_Cmd(DMA1_Stream1, DISABLE); 
   temp = USART3->SR;   
   temp = USART3->DR;  
   i = 16 - DMA_GetCurrDataCounter(DMA1_Stream1); 
   DMA_ClearFlag(DMA1_Stream1,DMA_FLAG_TCIF1 | DMA_FLAG_FEIF1 | DMA_FLAG_DMEIF1 | DMA_FLAG_TEIF1 | DMA_FLAG_HTIF1);//清除DMA1_Steam1传输完成标志 
    DMA_SetCurrDataCounter(DMA1_Stream1, 16); 
     receive_flag = 1; //????????1DMA_Cmd(DMA1_Stream1, ENABLE); 
  } 
} 
配置程序和中断服务函数如上,请大家帮我看看!或者大家一起讨论一下呀!我真的已经试了很多很多种方案! 
 
 
 
 |   
 
 
 
 
 
 |