STM32的串口DMA收发以及双缓冲区的实现
在使用STM32的UART的DMA功能总结如下:
首先上代码,这里采用STM32 的USART1作为Demo,RX的DMA为DMA1_Channel5,TX的DMA为DMA1_Channel4.初始化如下,红色的标记需要注意:
RX-DMA初始化
1 // DMA Rx 2 USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE); 3 DMA_Cmd(DMA1_Channel5,DISABLE); 4 DMA_InitStruct.DMA_PeripheralBaseAddr = (u32)(&USART1->DR); 5 DMA_InitStruct.DMA_MemoryBaseAddr = (u32)RxBuf0; 6 DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC; 7 DMA_InitStruct.DMA_BufferSize = 10; 8 DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 9 DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; 10 DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; 11 DMA_InitStruct.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte; 12 DMA_InitStruct.DMA_Mode = DMA_Mode_Circular; 13 DMA_InitStruct.DMA_Priority = DMA_Priority_High; 14 DMA_InitStruct.DMA_M2M = DMA_M2M_Disable; 15 DMA_Init(DMA1_Channel5,&DMA_InitStruct); 16 DMA_Cmd(DMA1_Channel5,ENABLE);
中断的初始化如下:
DMA_ITConfig(DMA1_Channel5,DMA_IT_TC,ENABLE);NVIC_InitStruct.NVIC_IRQChannel = DMA1_Channel5_IRQn;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStruct);//ENABLE DMA TX ISR DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);NVIC_InitStruct.NVIC_IRQChannel = DMA1_Channel4_IRQn;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStruct);
TX发送函数如下:
1 void USART1_SendDMA(uint8_t* buf,int len) 2 { 3 DMA_InitTypeDef DMA_InitStruct; 5 DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE); 6 7 DMA_Cmd(DMA1_Channel4,DISABLE); 8 9 DMA_InitStruct.DMA_PeripheralBaseAddr = (u32)(&USART1->DR); 10 DMA_InitStruct.DMA_MemoryBaseAddr = (u32)buf; 11 DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralDST; 12 DMA_InitStruct.DMA_BufferSize = len; 13 DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 14 DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; 15 DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; 16 DMA_InitStruct.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte; 17 DMA_InitStruct.DMA_Mode = DMA_Mode_Normal; 18 DMA_InitStruct.DMA_Priority = DMA_Priority_VeryHigh; 19 DMA_InitStruct.DMA_M2M = DMA_M2M_Disable; 20 DMA_Init(DMA1_Channel4,&DMA_InitStruct); 21 22 DMA_Cmd(DMA1_Channel4,ENABLE); 23 }
两个服务函数如下:
RX-DMA中断函数,实现RX的双缓冲区功能。值得注意的是,你的DMA设置成Normal模式的时候,在中断函数中就得设置DMABufferSize,应为Normal模式完成一次传输之后,BufferSize直接清零,设置成Circle模式就不会存在这个问题,下面的中断就是设置成Circle模式的。
void DMA1_Channel5_IRQHandler() {if(DMA_GetITStatus(DMA1_IT_TC5)){if(using_buf0 ==0){DMA1_Channel5->CMAR = (u32)RxBuf0;using_buf0 = 1; }else{DMA1_Channel5->CMAR = (u32)RxBuf1;using_buf0 = 0; }recv_flag = 1; DMA_ClearITPendingBit(DMA1_IT_TC5);} }
TX-DMA中断函数
void DMA1_Channel4_IRQHandler() {if(DMA_GetITStatus(DMA1_IT_TC4)){//TODO:Add code here DMA_ClearITPendingBit(DMA1_IT_TC4);} }
几点说明
1)这里采用双缓冲区的方式,对于大数据量的时候是很有效的,在处理一个缓冲区数据的时候,另外一个缓冲区能够正常接收数据
2)TX的DMA中断,可以采用类似于操作系统中互斥量的操作,当一个数组还在发送的时候,另外一个数组如果检测到一个在发送,则不能够进行发送,不然这样子数据会乱掉;
3)如果DMA接收想采用循环缓冲区的方式,可以直接将RX-DMA设置成Circle方式,然后数据就会硬件上自动实现环形缓冲区的功能,省了不少时间。
4)DMA在采用Normal模式的时候,当一次任务完成后,DMA->DMA_BufferSize自动清零,并且DMA自动停止。如果想再次设置DMA的BufferSize的话,必须要进行如下操作:
step1:DMA_CMD(DMAx_Channely,DISABLE);
step2: 设置DMA_BufferLen
step3:DMA_CMD(DMAx_Channely,ENABLE)
5)DMA采用Circle模式的时候,在发送或者接受完成之后,仍然保存着BufferSize,并且DMA还处于使能状态,一直连续工作,直到用户停止DMA
转载于:https://www.cnblogs.com/shangzhimeng/p/4154236.html
STM32的串口DMA收发以及双缓冲区的实现相关推荐
- STM32 串口DMA收发(二)
STM32 串口DMA收发数据 一.STM32 DMA简介与功能说明 1.STM32F4 DMA简介 DMA(Direct memory access),即直接存储器访问.用于在外设与存储器之间以及存 ...
- 嵌入式作业STM32采用串口DMA方式发送数据
目录 前言 要求 一.DMA的基本介绍 DMA的基本定义 DMA的主要特征 STM32F411x系列芯片DMA控制器 二.通过CubeMX配置项目 1.创建项目 2.选择芯片STM32F103C8T6 ...
- STM32F0系列串口DMA收发数据
关于STM32F0系列串口DMA收发数据详解 这里用的库函数版本,芯片型号为stm32f030c8t6.在用到串口DMA时,要按以下几个步骤进行. 1.确定使用的串口号,这里,我用的是usart2,对 ...
- 【华大测评】+串口DMA收发数据
串口传输用中断实现的话,要频繁的进入中断函数,这样无疑增加MCU的负担,干扰正常程序的运行,对于一些实时性强的应用,如数字显示应用中,液晶屏显示可能受影响而不能正常显示.用DMA实现串口收发数据,进行 ...
- STM32学习——串口数据收发
STM32学习--串口数据收发 ==STM32的串口通信== ==HAL库中串口发送的重要函数== ==STM32定时器实训== STM32的串口通信 异步串行通信:通信双方在没有同步时钟的前提下 ...
- stm32的串口DMA空闲中断接收不等长数据,stm32F1的usart1-DMA-IDLE收发
stm32的DMA收发原理,和stm32F4 + USART2 +DMA +IDLE使用,见另一篇:https://blog.csdn.net/Mark_md/article/details/1072 ...
- 【32单片机学习】(6)STM32串口+DMA收发不定长数据
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 1.DMA介绍 2.串口接收数据 3.实验现象 1.实验电路图 2.串口收发不定长数据视频演示 3.OLED 显示接收数据 ...
- STM32 进阶教程 15 - 串口DMA收发
前言 串口操作相信大家一定很熟悉,如果你已经会串口的收发数据,并可以灵活使用轮询及中断方式对串口进行数据收发,那么恭喜你,学完本节内容后,也将可以学会串口的更高级操作方式,DMA方式,DMA操作串口可 ...
- stm32的串口DMA空闲中断接收不等长数据,stm32F4的usart2-DMA-IDLE收发
1. 串口为什么要使用DMA?好处? 提高系统实时性:stm32单片机的串口没有FIFO,使用字节中断的方式去接收,会频繁进入中断,影响系统实时性.好在stm32的串口可以级联DMA使用,在大数据量连 ...
最新文章
- 面试准备工作 -戈多编程
- python quirk
- 多线程利器-队列(queue)
- 【CodeForces - 510D】Fox And Jumping(dp,stlmap,数论的性质)
- luogu P4070 [SDOI2016]生成魔咒
- d3 svg path添加文本_数据可视化——D3展现数据最炫丽的一面
- 马化腾300万奖励中国女排 网友:马云老师清空购物车还安排吗?
- 蓝桥杯 ADV-18 算法提高 实数相加
- jQuery事件相关方法
- 工具:Wind金融终端使用指南
- Web 项目中,MySQL 最新驱动下载、及配置
- Java笔试题大全(附带答案)
- JAVA毕业设计教务排课系统计算机源码+lw文档+系统+调试部署+数据库
- 基于NXP i.MX 8M Plus处理器的核心板和开发板有什么功能
- VR全景创业必看,热门功能帮助商家顺利出圈
- 互联网协议-简单理解和介绍
- 这些商业心理你了解吗?
- python字典一键多值_python一键多值
- android+照相软件,韩国很火的照相app
- 二叉排序树的查找、插入、创建和删除
热门文章
- python正则化_Python正则表达式
- python消息队列celery_python异步任务神器celery
- surface mesh framework运行
- html调用阅读模式,easyread.js—给网站开启阅读模式html教程
- python作品_智慧家居作品详细制作说明——3Done+Python+microbit创作
- vue main.js中引入js_手把手教你深入Vue3.0(Vue-cli4)项目打包性能优化实践
- 香港理工计算机qs排名,香港理工大学专业排名一览及最强专业推荐(QS世界大学排名)...
- dmz区服务器系统激活,dmz主机搭建服务器
- 多模块顺序_国考要上岸,每个模块要对多少题?
- 参考平面及其高度_施工现场平面布置关键点分析