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;
}
}
}
STM32串口DMA超时接收方法,可大大节约CPU时间的更多相关文章
- STM32 串口DMA方式接收(转)
STM32 是一款基于ARM Cortex-M3内核的32位MCU,主频最高可达72M.最近因为要在车机上集成TPMS功能, 便开始着手STM32的开发工作,STM32F10x系列共有5个串口(USA ...
- STM32 HAL库利用DMA实现串口不定长度接收方法
参考:https://blog.csdn.net/u014470361/article/details/79206352 我这里使用的芯片是 F1 系列的,主要是利用 DMA 数据传输方式实现的,在配 ...
- STM32串口DMA接收数据错位——暴力解决方法
背景:两片STM32通过串口通信,为了减小CPU负担,采用DMA进行通信,发送端为STM32F103C8T6,接收端为STM32F407VET6.在调试的过程中发现,一直出现数据错位的问题,接收端尝试 ...
- STM32串口USART1的使用方法和程序
通用同步异步收发器(USART)提供了一种灵活的方法来与使用工业标准NR 异步串行数据格式的外部设备之间进行全双工数据交换. USART利用分数波特率发生器提供宽范围的波特率选择,支持同步单向通信和半 ...
- STM32串口USART的使用方法和程序
通用同步异步收发器(USART)提供了一种灵活的方法来与使用工业标准NR 异步串行数据格式的外部设备之间进行全双工数据交换. USART利用分数波特率发生器提供宽范围的波特率选择,支持同步单向通信和半 ...
- STM32串口USART1的使用方法
前言: 通用同步异步收发器(USART)提供了一种灵活的方法来与使用工业标准NR 异步串行数据格式的外部设备之间进行全双工数据交换. USART利用分数波特率发生器提供宽范围的 波特率选择,支持同 ...
- STM32 ~ 串口DMA通道查找
STM32F4XX: /**************************************************************************************** ...
- STM32 HAL 库实现乒乓缓存加空闲中断的串口 DMA 收发机制,轻松跑上 2M 波特率
前言 直接储存器访问(Direct Memory Access,DMA),允许一些设备独立地访问数据,而不需要经过 CPU 介入处理.因此在访问大量数据时,使用 DMA 可以节约可观的 CPU 处理时 ...
- STM32之串口DMA接收不定长数据
STM32之串口DMA接收不定长数据 引言 在使用stm32或者其他单片机的时候,会经常使用到串口通讯,那么如何有效地接收数据呢?假如这段数据是不定长的有如何高效接收呢? 同学A:数据来了就会进入串口 ...
随机推荐
- Android事件分发流程总结
Action_Down 当按下一个控件,调用流程是Activity.dispatchTouchEvent -> ViewGroup.dispatchTouchEvent , 1.ViewGrou ...
- SQL总结——存储过程
SQL总结(五)存储过程 概念 存储过程(Stored Procedure):已预编译为一个可执行过程的一个或多个SQL语句. 创建存储过程语法 CREATE proc | procedure pro ...
- LOJ.6074.[2017山东一轮集训Day6]子序列(DP 矩阵乘法)
题目链接 参考yww的题解.本来不想写来但是他有一些笔误...而且有些地方不太一样就写篇好了. 不知不觉怎么写了这么多... 另外还是有莫队做法的...(虽然可能卡不过) \(60\)分的\(O(n^ ...
- DWM1000 长距离模块讨论
蓝点DWM1000 模块已经打样测试完毕,有兴趣的可以申请购买了,更多信息参见 蓝点论坛 正文: DWM1000 作为超宽室内带测距/定位的代表,官方给出的模块标准距离30-50m,而目前X宝上有很多 ...
- hihoCoder 1143 : 骨牌覆盖问题·一(递推,矩阵快速幂)
[题目链接]:click here~~ 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 骨牌,一种古老的玩具.今天我们要研究的是骨牌的覆盖问题: 我们有一个2xN的长条形 ...
- Python核心编程(第二版)正则表达式练习题解
15-1. 识别下列字符串:“bat,” “bit,” “but,” “hat,” “hit,” 或 “hut” from re import match word = raw_input('inpu ...
- GMA Round 1 抛硬币
传送门 抛硬币 扔一个硬币,正面概率为0.6.扔这枚硬币666次,正面就得3分,反面就得1分,求总分的方差. 直接套公式$np(1-p)*(X-Y)^2=666*0.6*(1-0.6)*(3-1)^2 ...
- poj3616 Milking Time(状态转移方程,类似LIS)
https://vjudge.net/problem/POJ-3616 猛刷简单dp的第一天第二题. 这道题乍一看跟背包很像,不同的在于它是一个区间,背包是定点,试了很久想往背包上套,都没成功. 这题 ...
- 说说GIL
上一篇:线程深入篇引入 Code:https://github.com/lotapp/BaseCode/tree/master/python/5.concurrent/Thread/3.GIL 说说G ...
- 发票打印不全不完整的解决方案(Win10)
发票不管怎么设置,不是二维码缺少一点,就是金额小数点后边的数字显示不全 具体原因是打印机默认纸张上A4,实际发票纸张要比A4宽度宽一点点 原来写过一篇程序方便的打印票据的控制<终于部分解决了.N ...