STM32F407单片机编程入门(十六) DMA详解及ADC-DMA方式采集含源码

news2024/11/14 21:09:47

文章目录

    • 一.概要
    • 二.STM32F407VET6单片机DMA外设特点
    • 三.STM32F407单片机DMA内部结构图
    • 四.DMA各通道请求
    • 五.STM32F407VET6单片机ADC-DMA采集例程
    • 六.工程源代码下载
    • 七.小结

一.概要

基本概念:
DMA是Direct Memory Access的首字母缩写,是一种完全由硬件执行数据交换的工作方式。DMA控制器从CPU接管对总线的控制,不经过CPU直接在内存和外设之间进行批量数据交换。DMA控制器向内存发出地址和控制信号,修改地址,对传送的字的个数计数,并且以中断方式向CPU报告传送操作的结束。 DMA方式一般用于高速传送成组数据。

DMA传输的三大要素:
传输源:DMA控制器从传输源读出数据;
传输目标:DMA控制器将数据传输的目标;
触发信号:用于触发一次数据传输的动作,执行一个单位的传输源至传输目标的数据传输;可以用来控制传输的时机。

DMA的主要优点:
由于CPU根本不参加传送操作,因此就省去了CPU取指令、取数、送数等操作。在数据传送过程中,没有保存现场、恢复现场之类的工作。内存地址修改、传送字个数的计数等等,也不是由软件实现,而是用硬件线路直接实现的。所以DMA方式能满足高速I/O设备的要求,也有利于CPU效率的发挥。

二.STM32F407VET6单片机DMA外设特点

● 双 AHB 主总线架构,一个用于存储器访问,另一个用于外设访问
● 仅支持 32 位访问的 AHB 从编程接口
● 每个 DMA 控制器有 8 个数据流,每个数据流有多达 8 个通道(或称请求)
● 每个数据流有单独的四级 32 位先进先出存储器缓冲区 (FIFO),可用于 FIFO 模式或直
接模式:
— FIFO 模式:可通过软件将阈值级别选取为 FIFO 大小的 1/4、1/2 或 3/4
— 直接模式
每个 DMA 请求会立即启动对存储器的传输。当在直接模式(禁止 FIFO)下将 DMA 请求配置为以存储器到外设模式传输数据时,DMA 仅会将一个数据从存储器预加载到内部 FIFO,从而确保一旦外设触发 DMA 请求时则立即传输数据。
● 通过硬件可以将每个数据流配置为:
— 支持外设到存储器、存储器到外设和存储器到存储器传输的常规通道
— 也支持在存储器方双缓冲的双缓冲区通道
● 8 个数据流中的每一个都连接到专用硬件 DMA 通道(请求)
● DMA 数据流请求之间的优先级可用软件编程(4 个级别:非常高、高、中、低),在软
件优先级相同的情况下可以通过硬件决定优先级(例如,请求 0 的优先级高于请求 1)
● 每个数据流也支持通过软件触发存储器到存储器的传输(仅限 DMA2 控制器)
● 可供每个数据流选择的通道请求多达 8 个。此选择可由软件配置,允许几个外设启动 DMA请求
● 要传输的数据项的数目可以由 DMA 控制器或外设管理:
— DMA 流控制器:要传输的数据项的数目是 1 到 65535,可用软件编程
— 外设流控制器:要传输的数据项的数目未知并由源或目标外设控制,这些外设通过
硬件发出传输结束的信号
● 独立的源和目标传输宽度(字节、半字、字):源和目标的数据宽度不相等时,DMA 自动封装/解封必要的传输数据来优化带宽。
● 每个数据流都支持循环缓冲区管理。
● 5 个事件标志(DMA 半传输、DMA 传输完成、DMA 传输错误、DMA FIFO 错误、直接
模式错误),进行逻辑或运算,从而产生每个数据流的单个中断请求。

三.STM32F407单片机DMA内部结构图

在这里插入图片描述

DMA控制器由4部分组成:

AHB 从接口配置DMA
AHB主接口进行数据传输
仲裁器进行DMA请求的优先级管理
数据处理和计数

四.DMA各通道请求

多个外设请求被映射到同一个DMA通道。这些请求信号在经过逻辑或后进入DMA。通过配置对应外设的寄存器,每个外设的请求均可以独立的开启或关闭。用户必须确保同一时间,在同一个通道上仅有一个外设的请求被开启。
在这里插入图片描述

在这里插入图片描述

以ADC1为例,可以映射到DMA2的Channel0

DMA的传输模式:

循环模式:用于处理一个环形的缓冲区,每轮传输结束时数据传输的配置会自动地更新为初始状态,DMA传输会连续不断地进行。 一般采用循环模式。
普通模式:在DMA传输结束时,DMA通道被自动关闭,进一步的DMA请求将不被满足。

外设到存储器传输数据流:
在这里插入图片描述

五.STM32F407VET6单片机ADC-DMA采集例程

STM32F407VET6开发板的PA4 引脚上的进行 ADC 电压采集,杜邦线连接 PA4 引脚与 VDD(3.3V),应该能读到单片机供电的电压值。
在这里插入图片描述

打开STM32CubeMX软件,新建工程
在这里插入图片描述
Part Number处输入STM32F407VE,再双击就创建新的工程
在这里插入图片描述

配置下载口引脚
在这里插入图片描述

配置外部晶振引脚
在这里插入图片描述

PA4,PA5引脚配置成ADC
在这里插入图片描述

DMA配置
在这里插入图片描述

中断使能
在这里插入图片描述

配置系统主频168Mhz,使用外部晶振
在这里插入图片描述

配置工程文件名,保存路径,KEIL5工程输出方式
在这里插入图片描述

生成工程
在这里插入图片描述

用Keil5打开工程
在这里插入图片描述

主要代码:

int ADCData;
uint16_t VolDta1,VolDta2;
__IO   uint16_t   aADCxConvertedData[2]; //存放2组数据,分别是ADC1_CH4,ADC1_CH5
__IO   uint8_t ubDmaTransferStatus = 2;//定义变量,在ADC采样结束,DMA传送完成置位,方便主程序取数据
//ADC数据采样结束回调函数,用于置位采样结束标志位
 void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
  /* Prevent unused argument(s) compilation warning */
   ubDmaTransferStatus=1;//置1
}
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_ADC1_Init();
  /* USER CODE BEGIN 2 */

if (HAL_ADC_Start_DMA(&hadc1,(uint32_t *)aADCxConvertedData,2) != HAL_OK)//启动ADC DMA传输
  {
    /* ADC conversion start error */
		Error_Handler();
  } 
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

	if (ubDmaTransferStatus == 1)//判断数据是否已经转换完成
    {
	  VolDta1=aADCxConvertedData[0]*3300/4095;//计算通道ADC1_Ch4采样到的电压值
	  VolDta2=aADCxConvertedData[1]*3300/4095;//计算通道ADC1_Ch5采样到的电压值			
      ubDmaTransferStatus = 0;//完成标志清0
    }
		
  }
  /* USER CODE END 3 */
}

实验结果:
PA4引脚的电压值VolDta1为3296mV,PA5引脚的电压值VolDta2为3297mV。
在这里插入图片描述

六.工程源代码下载

通过网盘分享的文件:18.ADC_DMA实验.zip
链接: https://pan.baidu.com/s/1dxaaRYC9Bk7E5NJ2vWLhtg 提取码: hfn5
如果链接失效,可以联系博主给最新链接
程序下载下来之后解压就行

七.小结

使用DMA进行数据收发能够提高数据传输的效率和可靠性。其次,使用DMA进行串口数据收发可以减轻CPU的负担。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2157969.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RK3568教学实验箱_操作教程:5-15 直流电机控制实验

一、产品简介 TL3568-PlusTEB人工智能实验箱 国产高性能处理器 64 位 4 核低功耗 2.0 GHz超高主频 1T 超高算力 NPU 兼容鸿蒙等国产操作系统 二、实验目的 1、熟悉Qt程序的开发流程; 2、掌握Qt Creator的基础开发使用; 3、通过编写Qt程序实现直流…

骨架行为识别-论文复现(论文复现)

骨架行为识别-论文复现(论文复现) 本文所涉及所有资源均在传知代码平台可获取 序言 骨架行为识别的定义 骨架行为识别是指通过分析人体骨架的运动轨迹和姿态,来识别和理解人体的行为动作。它是计算机视觉和模式识别领域的一个重要研究方向&a…

力扣上刷题之C语言实现-Days1

一. 简介 本文记录一下力扣的逻辑题。主要是数组方面的,使用 C语言实现。 二. 涉及数组的 C语言逻辑题 1. 两数之和 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target的那 两个 整数,并返回它们的…

C++笔试强训15、16、17

文章目录 笔试强训15一、选择题1-5题6-10题 二、编程题题目一题目二 笔试强训16一、选择题1-5题6-10题 二、编程题题目一题目二 笔试强训17一、选择题1-5题6-10题 二、编程题题目一题目二 笔试强训15 一、选择题 1-5题 共有派生下,派生类的成员函数只能访问基类的…

大模型训练不难,三步即可实现

前言 初步认识了大模型长什么样了,接下来一起来看看如何训练出一个大模型。 训练方式,这里主要参考OpenAI发表的关于InstructGPT的相关训练步骤,主流的大模型训练基本形式大多也是类似的: 1、预训练(Pretraining&a…

安卓13设置动态修改设置显示版本号 版本号增加信息显示 android13增加序列号

总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析4.代码修改5.编译6.彩蛋1.前言 设置 =》关于平板电脑 =》版本号 在这里显示了系统的一些信息,但是这里面的信息并不包含序列号之类的信息,我们修改下系统设置,在这里增加上相关的序列号。 2.问题分析…

C语言 使用scanf函数时出现错误代码C4996

文章目录 错误样式解决方法方法一:使用安全的函数替代方法二:禁用警告方法三:检查并修改编译器设置 错误样式 C4996 ‘scanf’: This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _C…

《算法岗面试宝典》正式发布

大家好,历时半年完善,《算法岗面试宝典》 终于可以跟大家见面了。 最近 ChatGPT 爆火,推动了技术圈对大模型算法场景落地的热情,就业市场招聘人数越来越多,算法岗一跃成为竞争难度第一的岗位。 岗位方向 从细分方向…

K8s Calico替换为Cilium,以及安装Cilium过程

一、删除Calico kubectl delete daemonset calico-node -n kube-systemkubectl delete deployment calico-kube-controllers -n kube-system kubectl delete ds kube-flannel-ds -n kube-system kubectl delete cm calico-config -n kube-system kubectl delete secret calico…

YOLOv5训练COCO2017数据集

网上没找到适合新手小白的教程,看了些教程,但还是没法解决自己遇到的问题。记录下自己的过程,希望能提供点帮助。 默认已经部署好了yolov5。 安装部署yolov5可参考以下: ubuntu20.04配置YOLOV5(非虚拟机)_ubuntu系统实现yolov5没有显卡-CSDN博客 目录 一、数据集下载…

Java基础-零拷贝

文章目录 什么是零拷贝?传统IO执行过程零拷贝的意义零拷贝的主要实现方式实际应用场景零拷贝的优势零拷贝的局限性 Java 中的零拷贝实现FileChannel.transferTo()FileChannel.transferFrom() 相关知识点解释什么是DMA内核空间和用户空间什么是用户态、内核态什么是上…

2012年408考研真题-数据结构

8.【2012统考真题】求整数n(n≥0)的阶乘的算法如下&#xff0c;其时间复杂度是(&#xff09;。 int fact(int n){ if(n<1) return 1; return n*fact (n-1); } A. O(log2n) B. O(n) C. O(nlog2n) D. O(n^2) 解析&#xff1a; 观察代码&#xff0c;我们不…

如何在openKylin中配置ssh服务并实现远程连接开放麒麟系统(1)

文章目录 前言1. 安装SSH服务2. 本地SSH连接测试3. openKylin安装Cpolar4. 配置 SSH公网地址5. 公网远程SSH连接6. 固定SSH公网地址7. SSH固定地址连接 前言 本文主要介绍如何在openKlyin系统中设置ssh连接&#xff0c;并结合cpolar内网穿透工具实现远程也可以ssh连接本地局域…

功能 接口测试,详解从抓包 +linux 日志 + 数据库的 bug 定位!

我在跟很多测试人员交流中发现&#xff0c;很大一部分测试工程师在进行功能和接口测试过程中&#xff0c;对于发现的bug很少去进行定位&#xff0c;只是将bug基于业务操作上如何出现的&#xff0c;进行描述&#xff1b;至于bug产生的原因&#xff0c;开发自己排查去吧。本文中&…

多语言文本 AI 纠错格式化 API 数据接口

多语言文本 AI 纠错格式化 API 数据接口 AI / 文本处理 AI 模型智能纠正 语法纠错 / 文本格式化。 1. 产品功能 支持多语言文本的语法纠错&#xff1b;自动识别并纠正拼写错误、语法错误和标点符号使用不当&#xff1b;优化文本格式&#xff0c;提高可读性&#xff1b;基于AI…

《李·斯莫林讲量子引力》:在不断运动的宇宙中探究离散的时空

可能是斯莫林的书读得并不多&#xff0c;感觉他讲故事的能力不如讲物理定律的能力。前半部分纯知识的可读性要好于后面讲述理论的创造过程的故事。如作者所说现代科学没有任何领域是单打独斗&#xff0c;而是不断探索&#xff0c;在团队中&#xff0c;前人和其他专业领域专家合…

vue使用PDF.JS踩的坑--部署到服务器上显示pdf.mjs viewer.mjs找不到资源

之前项目使用的pdf.js 是2.15.349版本&#xff0c;最近换了一个4.6.82的版本&#xff0c;在本地上浏览文件运行的好好的&#xff0c;但是发布到服务器&#xff08;IIS&#xff09;上打不开文件&#xff0c;控制台提示找不到pdf.mjs viewer.mjs。 之前使用的2.15.349pdf和viewer…

76、Python之函数式编程:柯里化都不懂,别说你会函数式编程

引言 很多时候&#xff0c;我们在定义函数处理比较复杂的业务逻辑时&#xff0c;首先是想着遵照“单一职能原则&#xff08;SRP&#xff09;”&#xff0c;尽量拆分为功能单一、足够精简的函数&#xff0c;以便保证代码的可读性和可扩展性。但是&#xff0c;有些逻辑就是没法拆…

2024年双十一有什么好物值得买呢?双十一必买好物清单

双十一买什么犒劳自己既不会浪费钱又可以增添生活的幸福感&#xff1f;以下就整理了五款更适合与秋冬独自生活相伴的好物&#xff0c;精致增加生活氛围感&#xff0c;热爱生活的同时更好的爱自己&#xff01;努力工作和生活当然也要更好的享受生活&#xff0c;给生活创造更多美…

Vue(14)——组合式API①

setup 特点&#xff1a;执行实际比beforeCreate还要早&#xff0c;并且获取不到this <script> export default{setup(){console.log(setup函数);},beforeCreate(){console.log(beforeCreate函数);} } </script> 在setup函数中提供的数据和方法&#xff0c;想要在…