STM32串口DMA超時接收方法,可大大節約CPU時間


//超時時間定義
#define        UART1_TimeoutComp 2  //20ms
#define        UART2_TimeoutComp 10  //100ms
#define        UART3_TimeoutComp 10  //100ms


u8 UART1_Timeout,UART2_Timeout,UART3_Timeout;
u16 UART1_FlagTemp,UART2_FlagTemp,UART3_FlagTemp;
u8 uart1_data_temp[200],uart2_data_temp[500],uart3_data_temp[500];

//定時器初始化
void TimerInit(void)
{
   //定時器初始化數據結構定義
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
   //初始化定時器,用於超時接收,20ms

        TIM_TimeBaseStructure.TIM_Period           = 100;                //計數上限,100*100us = 10000us = 10ms
        TIM_TimeBaseStructure.TIM_Prescaler        = 4799;        //預分頻4800,48MHz主頻,分頻後時鐘週期100us
        TIM_TimeBaseStructure.TIM_ClockDivision    = TIM_CKD_DIV1;  //不分頻
        TIM_TimeBaseStructure.TIM_CounterMode      = TIM_CounterMode_Up;  //向上計數
        TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
        //初始化
        TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);



  DMA_DeInit(DMA1_Channel5); //將DMA的通道1寄存器重設爲缺省值
  DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)SRC_USART1_DR; //源頭BUF既是 (&(USART1->DR))
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)uart1_data_temp; //目標BUF 既是要寫在哪一個個數組之中 
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //外設做源頭//外設是做爲數據傳輸的目的地仍是來源 
  DMA_InitStructure.DMA_BufferSize = 200; //DMA緩存的大小 單位在下邊設定
  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_PeripheralDataSize_Byte; //內存字節爲單位
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //工做在循環緩存模式
  DMA_InitStructure.DMA_Priority = DMA_Priority_High; //4優先級之一的(高優先)VeryHigh/High/Medium/Low
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //非內存到內存 
  DMA_Init(DMA1_Channel5, &DMA_InitStructure); //根據DMA_InitStruct中指定的參數初始化DMA的通道1寄存器 
  DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE); //DMA5傳輸完成中斷 
  USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE); //使能USART1的接收DMA請求

//串口初始化,只列出一個通道,其餘兩個通道相同        
void USART1_Configuration(void)
{
    //串口初始化數據結構定義
        USART_InitTypeDef USART_InitStructure; 

//定時器中斷服務程序
void TIM2_IRQHandler(void)
{
  u16 i;   
  //清定時器中斷
  TIM_ClearITPendingBit(TIM2, TIM_FLAG_Update); 

  if(i!=uart1_Flag_last)  //未完成傳輸
  {
          UART1_Timeout=0;
        uart1_Flag_last=i;
  }
  else
  {
    if(UART1_Timeout>UART1_TimeoutComp)  //產生超時
        {
           if(i<200) //有數據接收到
           {
                  UART1_FlagTemp=200-i;      //獲得接收到的字節數
              
                for(i=0;i<UART1_FlagTemp;i++)  //將數據拷貝到緩衝區
                 uart1_data[i]=uart1_data_temp[i];
                UART1_Flag=UART1_FlagTemp;
                
                DMA_ClearFlag(DMA1_FLAG_TC5);
                DMA_Cmd(DMA1_Channel5, DISABLE); //正式容許DMA                 
                DMA5_Init();                  
           }
           UART1_Timeout=0;
        }
  }
  //------------------------------------------------------------------
  i=DMA_GetCurrDataCounter(DMA1_Channel6);
  DMA_ClearITPendingBit(DMA1_IT_GL6); //清除所有中斷標誌

                for(i=0;i<UART2_FlagTemp;i++)  //將數據拷貝到緩衝區
                 uart2_data[i]=uart2_data_temp[i];
                UART2_Flag=UART2_FlagTemp;
                
                DMA_ClearFlag(DMA1_FLAG_TC6);
                DMA_Cmd(DMA1_Channel6, DISABLE); //正式容許DMA                 
                DMA6_Init();
                                
           }
           UART2_Timeout=0;
        }
  }
  //------------------------------------------------------------------
  i=DMA_GetCurrDataCounter(DMA1_Channel3);
  DMA_ClearITPendingBit(DMA1_IT_GL3); //清除所有中斷標誌
                for(i=0;i<UART3_FlagTemp;i++)  //將數據拷貝到緩衝區                 uart3_data[i]=uart3_data_temp[i];                UART3_Flag=UART3_FlagTemp;                                DMA_ClearFlag(DMA1_FLAG_TC3);                DMA_Cmd(DMA1_Channel3, DISABLE); //正式容許DMA                                 DMA3_Init();                             }           UART3_Timeout=0;        }  }  }
相關文章
相關標籤/搜索