//超时时间定义
#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;
        }
  }  
}

STM32串口DMA超时接收方法,可大大节约CPU时间的更多相关文章

  1. STM32 串口DMA方式接收(转)

    STM32 是一款基于ARM Cortex-M3内核的32位MCU,主频最高可达72M.最近因为要在车机上集成TPMS功能, 便开始着手STM32的开发工作,STM32F10x系列共有5个串口(USA ...

  2. STM32 HAL库利用DMA实现串口不定长度接收方法

    参考:https://blog.csdn.net/u014470361/article/details/79206352 我这里使用的芯片是 F1 系列的,主要是利用 DMA 数据传输方式实现的,在配 ...

  3. STM32串口DMA接收数据错位——暴力解决方法

    背景:两片STM32通过串口通信,为了减小CPU负担,采用DMA进行通信,发送端为STM32F103C8T6,接收端为STM32F407VET6.在调试的过程中发现,一直出现数据错位的问题,接收端尝试 ...

  4. STM32串口USART1的使用方法和程序

    通用同步异步收发器(USART)提供了一种灵活的方法来与使用工业标准NR 异步串行数据格式的外部设备之间进行全双工数据交换. USART利用分数波特率发生器提供宽范围的波特率选择,支持同步单向通信和半 ...

  5. STM32串口USART的使用方法和程序

    通用同步异步收发器(USART)提供了一种灵活的方法来与使用工业标准NR 异步串行数据格式的外部设备之间进行全双工数据交换. USART利用分数波特率发生器提供宽范围的波特率选择,支持同步单向通信和半 ...

  6. STM32串口USART1的使用方法

    前言: 通用同步异步收发器(USART)提供了一种灵活的方法来与使用工业标准NR 异步串行数据格式的外部设备之间进行全双工数据交换. USART利用分数波特率发生器提供宽范围的   波特率选择,支持同 ...

  7. STM32 ~ 串口DMA通道查找

    STM32F4XX: /**************************************************************************************** ...

  8. STM32 HAL 库实现乒乓缓存加空闲中断的串口 DMA 收发机制,轻松跑上 2M 波特率

    前言 直接储存器访问(Direct Memory Access,DMA),允许一些设备独立地访问数据,而不需要经过 CPU 介入处理.因此在访问大量数据时,使用 DMA 可以节约可观的 CPU 处理时 ...

  9. STM32之串口DMA接收不定长数据

    STM32之串口DMA接收不定长数据 引言 在使用stm32或者其他单片机的时候,会经常使用到串口通讯,那么如何有效地接收数据呢?假如这段数据是不定长的有如何高效接收呢? 同学A:数据来了就会进入串口 ...

随机推荐

  1. Flask实例化配置

    template_folder :指定模板存放路径,默认值:temolates from flask import Flask, url_for app = Flask(__name__,templa ...

  2. WebKit discarded an uncaught exception in the webView:decidePolicyForNavigationAction:request:frame:decisionListener: delegate: <NSInvalidArgumentException> -[__NSArrayM objectForKey:]: unrecognized s

    <!DOCTYPE html> <html> <head> <title></title> <meta http-equiv=&quo ...

  3. Celery框架

    在学习Celery之前,我先简单的去了解了一下什么是生产者消费者模式. 生产者消费者模式 在实际的软件开发过程中,经常会碰到如下场景:某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是 ...

  4. R语言语法基础二

    R语言语法基础二 重塑数据 增加行和列 # 创建向量 city = c("Tampa","Seattle","Hartford"," ...

  5. elment ui 图片上传遇到的一些问题

    图片上传返回200,message显示请上传图片 注意上图中的name字段要和服务器接受的name相同,这里我们是imgfile,默认name不是这个,所以要在el-upload组件上设置name属性 ...

  6. Vue(十四)过渡(动画)

    过渡(动画) 1. 简介 Vue 在插入.更新或者移除 DOM 时,提供多种不同方式的应用过渡效果 本质上还是使用CSS3动画:transition.animation 2. 基本用法 使用trans ...

  7. 11 week blog

    Obtaining the JSON: 1.首先,我们将把要检索的JSON的URL存储在变量中. 2.要创建请求,我们需要使用new关键字从XMLHttpRequest构造函数创建一个新的请求对象实例 ...

  8. JAVA自学笔记26

    JAVA自学笔记26 1.网络编程 1)用来实现网络互联的不同计算机上运行的程序可以进行数据交换 2)网络模型一般泛指 OSI:(Open System Interconnection)开放系统互联参 ...

  9. jQuery 学习03——HTML:捕获、设置、添加元素、删除元素、CSS类、CSS()方法、尺寸

    jQuery - 获取内容text().html() 以及 val()和属性attr() jQuery 中非常重要的部分,就是操作 DOM 的能力. DOM = Document Object Mod ...

  10. MySQL优化之like关键字

    1.%号不放最左边 无法使用索引了,开头是不确定的,MySQL也无法进行优化了,只能扫描表了. 2.使用覆盖索引 如果业务需要%就放开头我们也没办法,一般情况需求都是这样的,毕竟优化还是为业务服务的. ...