DMA,全称为:Direct Memory Access,即直接存储器访问。DMA传输方式无需CPU直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为RAM与I/O设备开辟一条直接传送数据的通路,能使CPU的效率大为提高。

DMA设置的一般步骤可以总结为如下几个步骤:

1.DMA时钟使能

2.DMA设置复位

3.设置DMA基地址,内存地址,输出方向参数

4.设置DMA数据大小,优先级,使用通道参数

5.DMA工作方式初始化

6.使能DMA

7.编写中断处理函数

前端采集模块的DMA使用主要用于ADC采集结果的传输和USART串口的数据发送传输。根据《stm32中文参考手册》的DMA请求一览表,选用了DMA1的通道1作为ADC1的数据传输通道,以及DMA1通道4作为和USART串口的数据发送传输通道。此处采用了单个DMA复用多通道的设计,是因为DMA速度足以完成这些任务,而且留下其他DMA资源以便项目以后可以扩展,达到节省资源的目的。

USART使用DMA发送数据配置和使能代码

  1. //DMA1的各通道配置
  2. //这里的传输形式是固定的,这点要根据不同的情况来修改
  3. //从存储器->外设模式/8位数据宽度/存储器增量模式
  4. //DMA_CHx:DMA通道CHx
  5. //cpar:外设地址
  6. //cmar:存储器地址
  7. //cndtr:数据传输量
  8. void DMA_USART_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
  9. {
  10. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  //使能DMA传输
  11. DMA_DeInit(DMA_CHx);   //将DMA的通道1寄存器重设为缺省值
  12. DMA1_MEM_LEN=cndtr;
  13. DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;  //DMA外设ADC基地址
  14. DMA_InitStructure.DMA_MemoryBaseAddr = cmar;  //DMA内存基地址
  15. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  //数据传输方向,从内存读取发送到外设
  16. DMA_InitStructure.DMA_BufferSize = cndtr;  //DMA通道的DMA缓存的大小
  17. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变
  18. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增
  19. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //数据宽度为8位
  20. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位
  21. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  //工作在正常缓存模式
  22. DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级
  23. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输
  24. DMA_Init(DMA_CHx, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
  25. }
  26. //开启一次DMA传输
  27. void DMA_USART_Enable(DMA_Channel_TypeDef*DMA_CHx)
  28. {
  29. DMA_Cmd(DMA_CHx, DISABLE );  //关闭USART1 TX DMA1 所指示的通道
  30. DMA_SetCurrDataCounter(DMA_CHx, DMA1_MEM_LEN);//DMA通道的DMA缓存的大小
  31. DMA_Cmd(DMA_CHx, ENABLE);  //使能USART1 TX DMA1 所指示的通道
  32. }

ADC使用DMA传送多通道数据配置和使能代码

  1. //DMA1的各通道配置
  2. //这里的传输形式是固定的,这点要根据不同的情况来修改
  3. //从存储器->外设模式/8位数据宽度/存储器增量模式
  4. //DMA_CHx:DMA通道CHx
  5. //cpar:外设地址
  6. //cmar:存储器地址
  7. //cndtr:数据传输量
  8. void DMA_ADC_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
  9. {
  10. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  //使能DMA传输
  11. DMA_DeInit(DMA_CHx); //将DMA的通道1寄存器重设为缺省值
  12. DMA_InitStructure.DMA_PeripheralBaseAddr = cpar; //DMA外设ADC基地址
  13. DMA_InitStructure.DMA_MemoryBaseAddr = cmar; //DMA内存基地址
  14. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //内存作为数据传输的目的地
  15. DMA_InitStructure.DMA_BufferSize = cndtr; //DMA通道的DMA缓存的大小
  16. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变
  17. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增
  18. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //数据宽度为16位
  19. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度为16位
  20. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //工作在循环缓存模式
  21. DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道 x拥有高优先级
  22. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输
  23. DMA_Init(DMA_CHx, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道
  24. }
  25. //开启一次DMA传输
  26. void DMA_ADC_Enable(DMA_Channel_TypeDef*DMA_CHx)
  27. {
  28. DMA_Cmd(DMA_CHx, DISABLE );  //关闭USART1 TX DMA1 所指示的通道
  29. DMA_Cmd(DMA_CHx, ENABLE);  //使能USART1 TX DMA1 所指示的通道
  30. }

这里需要注意的是USART使用DMA发送数据需要每一次都重新使能,即每发送一次数据使能一下。

而ADC使用DMA传送多通道数据则只需要使能一次就可以自动循环工作,只需从数组空间读取ADC数据。

STM32f103的数电采集电路的DMA设计和使用优化程序的更多相关文章

  1. STM32f103的数电采集电路的双ADC的设计与使用

    STM32F103C8T6拥有3个ADC,其独立使用已经在本文的3.1.3里面有详细的介绍,这里主要是介绍双ADC的同时使用,即STM32的同步规则模式使用.在此模式在规则通道组上执行时,外部触发来自 ...

  2. STM32f103的数电采集电路的TIMER定时器的使用与时序控制的程序

    STM32 的通用定时器是一个通过可编程预分频器(PSC)驱动的 16 位自动装载计数器(CNT)构成.STM32 的通用定时器可以被用于:测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较 ...

  3. 数电课设——琐碎

    这几天没有更新过网站了,也没继续开发VellLock了,可是感觉还是没有闲着,一直在跟下面的一些元器件在打交道,当然下面的都是小儿科,英文文档都看得我快吐血了.数电基本属于棺材边上过的我,是各种头大, ...

  4. 模电&数电知识整理(不定期更新)

    模电总复习之爱课堂题目概念整理 Chapter 1 1) 设室温情况下某二极管的反偏电压绝对值为1V,则当其反偏电压值减少100mV时,反向电流的变化是基本不发生变化. 2) 二极管发生击穿后,在击穿 ...

  5. DMA设计

    目录 DMA设计 DMA框架 手册请看英文手册 芯片特性 请求来源 协议简述 基本时序 模式 协议 数据大小的描述 具体完整的实例时序 代码设计 驱动程序 测试程序 测试 参考链接 title: DM ...

  6. 【转】基于APD的光电探测器电路研究与设计

    光电探测器电路用于对光电转换器件输出的微弱电压或电流信号进行放大.处理和整形输出.对于不同探测用途而采用的光电转换器件不同,与之配合使用的光电探测器电路性能也因此而不同.如果用来进行光电转换,则重点考 ...

  7. Java生鲜电商平台-商品价格的设计与架构

    Java生鲜电商平台-商品价格的设计与架构 说明:Java开源生鲜电商平台-商品价格的设计与架构,主要是对商品的价格进行研究与系统架构. 一.常见的电商价格 市场价(List Price):这个价格仅 ...

  8. Java开源生鲜电商平台-监控模块的设计与架构(源码可下载)

    Java开源生鲜电商平台-监控模块的设计与架构(源码可下载) 说明:Java开源生鲜电商平台-监控模块的设计与架构,我们谈到监控,一般设计到两个方面的内容: 1. 服务器本身的监控.(比如:linux ...

  9. Java开源生鲜电商平台-通知模块设计与架构(源码可下载)

    Java开源生鲜电商平台-通知模块设计与架构(源码可下载) 说明:对于一个生鲜的B2B平台而言,通知对于我们实际的运营而言来讲分为三种方式:           1. 消息推送:(采用极光推送)   ...

随机推荐

  1. android monitor 汉化 ddms

    作者:韩梦飞沙 Author:han_meng_fei_sha 邮箱:313134555@qq.com E-mail: 313134555 @qq.com android.jar\com\androi ...

  2. ab测试swoole和ngixn+php-fpm对比

    做个swoole http_server和ngixn+php7-fpm测试 nginx swoole卓越的性能让我惊呆了   如需应用可nginx反代, swoole作为http_server, 不用 ...

  3. 2041 ACM 超级楼梯

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2041 数学问题,找规律,可以先假设全一步,然后一个两步的,两个两步的~~.很容易发现规律:F[N]=F[N ...

  4. php 允许浏览器跨域访问web服务端的解决方案

    今天和同事探讨了前后端如何真正实现隔离开发的问题,如果前端单独作为服务发布,势必会涉及到无法直接调用后端的接口的问题,因为浏览器是不允许跨域提交请求的. 所谓跨域访问,就是在浏览器窗口,和某个服务端通 ...

  5. 认证登录装饰器与form组件的使用

    def auth(func): '''制作登录认证的装饰器''' def inner(request,*args,**kwargs): user_info=request.session.get(se ...

  6. BZOJ4261 : 建设游乐场

    将图黑白染色,每个点拆成两个点,分别表示水平和竖直方向,再增加一个点以控制流量,那么每个格子都需要找两个方向去连接. $S$到每个黑点的控制点连边,流量$2$,费用$0$: 控制点向两个方向的点各连两 ...

  7. 3dmax多个版本软件的安装包以及安装教程

    这个文档具体出自哪里,我也是记不得了,需要的看下,链接如果是失效,那我也无能为力了. 免费分享,链接永久有效 2014版3D MAX链接:http://pan.baidu.com/s/1nuFr7Xv ...

  8. og4j日志文件乱码问题的解决方法

    现象:在默认语言非中文(或者说默认语言不支持中文的)的Windows.Linux.Unix上,用log4j打印日志,出现乱码,常见的就是一堆问号. 解决方法: 如果是log4j.properties为 ...

  9. Kubernetes中的亲和性与反亲和性

    通常情况下,Pod分配到哪些Node是不需要管理员操心的,这个过程会由scheduler自动实现.但有时,我们需要指定一些调度的限制,例如某些应用应该跑在具有SSD存储的节点上,有些应用应该跑在同一个 ...

  10. MySQL查看数据库表容量大小

    本文介绍MySQL查看数据库表容量大小的命令语句,提供完整查询语句及实例,方便大家学习使用. 1.查看所有数据库容量大小 select table_schema as '数据库', sum(table ...