STM32串口DMA空闲中断求救

2019-12-13 18:31发布

本帖最后由 yangzi8000 于 2019-2-12 11:42 编辑

F1使用串口3  DMA空闲中断,设置缓冲区100个字节,发现每次接收到》100个字节才产生一次空闲中断,如何修改设置成接收不定长字节就能空闲中断,贴代码:
void uart_init(u32 bound)
{
   
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    DMA_InitTypeDef DMA_InitStructure;

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //??USART1,GPIOA??
   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //??DMA??
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);//??USART2??

   USART_DeInit(USART3);  //????1

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //??????
    GPIO_Init(GPIOB, &GPIO_InitStructure); //???PA9
   

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//????
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    //Usart1 NVIC ??
    NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//?????3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //????3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ????
    NVIC_Init(&NVIC_InitStructure); //??????????VIC???
  
   //USART ?????
  USART_InitStructure.USART_BaudRate = bound;//?????9600;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;//???8?????
  USART_InitStructure.USART_StopBits = USART_StopBits_1;//?????
  USART_InitStructure.USART_Parity = USART_Parity_No;//??????
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//????????
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //????

    USART_Init(USART3, &USART_InitStructure); //?????
    USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);//??????
    USART_DMACmd(USART3,USART_DMAReq_Rx,ENABLE);   //????1 DMA??
    USART_Cmd(USART3, ENABLE);                    //????

    //???DMA??
  DMA_DeInit(DMA1_Channel3);   //?DMA???5?????????  ??1????DMA??5
  DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART3->DR;  //DMA??ADC???
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)RxBuffer3;  //DMA?????
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  //??????,??????????
  DMA_InitStructure.DMA_BufferSize = 100;  //DMA???DMA?????
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //?????????
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //?????????
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //?????8?
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //?????8?
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  //?????????
  DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA?? x??????
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA??x????????????
  DMA_Init(DMA1_Channel3, &DMA_InitStructure);  //??DMA_InitStruct?????????DMA???

    DMA_Cmd(DMA1_Channel3, ENABLE);  //????DMA??
}       

u8 flag1=0;
void USART3_IRQHandler(void)         
{       
     if(USART_GetFlagStatus(USART3,USART_IT_IDLE)!= RESET)       
           {
             u8 num;
            num = USART3->SR;      
            num = USART3->DR; //?USART_IT_IDLE??      
            DMA_Cmd(DMA1_Channel3,DISABLE);    //??DMA      
            num = 100 -  DMA_GetCurrDataCounter(DMA1_Channel3);      //??????????        
            RxBuffer3[num] = '';      
            DMA1_Channel3->CNDTR=100;       //??????????         
            DMA_Cmd(DMA1_Channel3,ENABLE);  //??DMA     
            flag1=1;           //????????1
          }
          
                                         
       
                                 

}       
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
9条回答
zstu2012
1楼-- · 2019-12-14 12:57
看发送端字节间隔,标准的就用总线空闲标志位idle;要是间隔规则但间隔时间长的用定时器超时检测;没规律的就只能单个字节接受或者用大缓冲接收后再慢慢分析
XA144F
2楼-- · 2019-12-14 18:28
空闲中断再启动一个定时器,等到溢出中断了才认为接收完成。
honami520
3楼-- · 2019-12-14 20:45
这个有什么好讨论的。无非是开了个DMA接收数据,然后又开了空闲中断。好比DMA缓存区100字节。正常的通信指令可能就1-20个字节。收到1-20个字节就空闲,然后去DMA拿数据就好了。
楼主是代码没写好,于是发生了,非要发100个字节才能中断。那你这个是DMA接收完成中断,而不是空闲中断。
看一下库的例子吧。这种都是基础代码了。没什么好讨论的

一周热门 更多>