zoukankan      html  css  js  c++  java
  • 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;
            }
      }  
    }
  • 相关阅读:
    制作企业IT解决方案的几项训练
    Community Server 1.0 Beta安装使用记录
    SharePoint Portal Server定制之区域模板定义
    从售前工作的角度了解SharePoint产品和技术
    活动目录的应用组策略
    企业客户组织结构在售前工作中的作用
    Community Server 1.0 Beta安装使用记录(二)
    2004年钢铁行业信息化现状
    IT解决方案编写小结
    关于软件系统架构设计的一些新思想
  • 原文地址:https://www.cnblogs.com/zym0805/p/7339913.html
Copyright © 2011-2022 走看看