在使用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收发以及双缓冲区的实现相关推荐

  1. STM32 串口DMA收发(二)

    STM32 串口DMA收发数据 一.STM32 DMA简介与功能说明 1.STM32F4 DMA简介 DMA(Direct memory access),即直接存储器访问.用于在外设与存储器之间以及存 ...

  2. 嵌入式作业STM32采用串口DMA方式发送数据

    目录 前言 要求 一.DMA的基本介绍 DMA的基本定义 DMA的主要特征 STM32F411x系列芯片DMA控制器 二.通过CubeMX配置项目 1.创建项目 2.选择芯片STM32F103C8T6 ...

  3. STM32F0系列串口DMA收发数据

    关于STM32F0系列串口DMA收发数据详解 这里用的库函数版本,芯片型号为stm32f030c8t6.在用到串口DMA时,要按以下几个步骤进行. 1.确定使用的串口号,这里,我用的是usart2,对 ...

  4. 【华大测评】+串口DMA收发数据

    串口传输用中断实现的话,要频繁的进入中断函数,这样无疑增加MCU的负担,干扰正常程序的运行,对于一些实时性强的应用,如数字显示应用中,液晶屏显示可能受影响而不能正常显示.用DMA实现串口收发数据,进行 ...

  5. STM32学习——串口数据收发

    STM32学习--串口数据收发 ==STM32的串口通信== ==HAL库中串口发送的重要函数== ==STM32定时器实训== STM32的串口通信   异步串行通信:通信双方在没有同步时钟的前提下 ...

  6. stm32的串口DMA空闲中断接收不等长数据,stm32F1的usart1-DMA-IDLE收发

    stm32的DMA收发原理,和stm32F4 + USART2 +DMA +IDLE使用,见另一篇:https://blog.csdn.net/Mark_md/article/details/1072 ...

  7. 【32单片机学习】(6)STM32串口+DMA收发不定长数据

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 1.DMA介绍 2.串口接收数据 3.实验现象 1.实验电路图 2.串口收发不定长数据视频演示 3.OLED 显示接收数据 ...

  8. STM32 进阶教程 15 - 串口DMA收发

    前言 串口操作相信大家一定很熟悉,如果你已经会串口的收发数据,并可以灵活使用轮询及中断方式对串口进行数据收发,那么恭喜你,学完本节内容后,也将可以学会串口的更高级操作方式,DMA方式,DMA操作串口可 ...

  9. stm32的串口DMA空闲中断接收不等长数据,stm32F4的usart2-DMA-IDLE收发

    1. 串口为什么要使用DMA?好处? 提高系统实时性:stm32单片机的串口没有FIFO,使用字节中断的方式去接收,会频繁进入中断,影响系统实时性.好在stm32的串口可以级联DMA使用,在大数据量连 ...

最新文章

  1. 面试准备工作 -戈多编程
  2. python quirk
  3. 多线程利器-队列(queue)
  4. 【CodeForces - 510D】Fox And Jumping(dp,stlmap,数论的性质)
  5. luogu P4070 [SDOI2016]生成魔咒
  6. d3 svg path添加文本_数据可视化——D3展现数据最炫丽的一面
  7. 马化腾300万奖励中国女排 网友:马云老师清空购物车还安排吗?
  8. 蓝桥杯 ADV-18 算法提高 实数相加
  9. jQuery事件相关方法
  10. 工具:Wind金融终端使用指南
  11. Web 项目中,MySQL 最新驱动下载、及配置
  12. Java笔试题大全(附带答案)
  13. JAVA毕业设计教务排课系统计算机源码+lw文档+系统+调试部署+数据库
  14. 基于NXP i.MX 8M Plus处理器的核心板和开发板有什么功能
  15. VR全景创业必看,热门功能帮助商家顺利出圈
  16. 互联网协议-简单理解和介绍
  17. 这些商业心理你了解吗?
  18. python字典一键多值_python一键多值
  19. android+照相软件,韩国很火的照相app
  20. 二叉排序树的查找、插入、创建和删除

热门文章

  1. python正则化_Python正则表达式
  2. python消息队列celery_python异步任务神器celery
  3. surface mesh framework运行
  4. html调用阅读模式,easyread.js—给网站开启阅读模式html教程
  5. python作品_智慧家居作品详细制作说明——3Done+Python+microbit创作
  6. vue main.js中引入js_手把手教你深入Vue3.0(Vue-cli4)项目打包性能优化实践
  7. 香港理工计算机qs排名,香港理工大学专业排名一览及最强专业推荐(QS世界大学排名)...
  8. dmz区服务器系统激活,dmz主机搭建服务器
  9. 多模块顺序_国考要上岸,每个模块要对多少题?
  10. 参考平面及其高度_施工现场平面布置关键点分析