STM32入门——DMA数据搬运工

news2024/11/22 6:09:22

DMA简介

  • DMA(Direct Memory Access)直接存储器存取
  • DMA可以提供外设和存储器或者存储器和存储器之间的高速数据传输,无须CPU干预,节省了CPU的资源
  • 12个独立可配置的通道: DMA1(7个通道), DMA2(5个通道) 每个通道都支持软件触发和特定的硬件触发
  • STM32F103C8T6 DMA资源:DMA1(7个通道)

存储器映像

在这里插入图片描述
DMA框图
在这里插入图片描述
DMA基本结构
在这里插入图片描述
自动重装器:转运完成后恢复到初值,决定单次转换还是循环转换
M2M:0位硬件触发(外设到存储器或者存储器到外设),1为软件触发(存储器到存储器)
传输计数器:触发一次,转运一次,计数器减1.
*写传输计数器时,要先关闭DAM使能
DMA请求
在这里插入图片描述

数据宽度与对齐
在这里插入图片描述
数据转运+DMA
在这里插入图片描述

#include "DMA.h"
uint16_t SIZE;
void myDMA_Init(uint32_t AddrA,uint32_t AddrB,uint16_t Size)
{
	//开启时钟
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
	
	SIZE = Size;
	DMA_InitTypeDef DMA_InitStructure;
	DMA_InitStructure.DMA_BufferSize = Size;
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//传输方向
	DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;//触发方式
	DMA_InitStructure.DMA_MemoryBaseAddr = AddrB;//目标地址
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//字节
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//是否自动重装
	DMA_InitStructure.DMA_PeripheralBaseAddr = AddrA;//源地址
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//字节
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;//地址是否递增
	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//优先级
	DMA_Init(DMA1_Channel1,&DMA_InitStructure);
	
	
	DMA_Cmd(DMA1_Channel1,DISABLE);
	
}

void myDMA_Transmission(void)
{
	DMA_Cmd(DMA1_Channel1,DISABLE);
	DMA_SetCurrDataCounter(DMA1_Channel1,SIZE);
	DMA_Cmd(DMA1_Channel1,ENABLE);
	
	while(DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET);
	DMA_ClearFlag(DMA1_FLAG_TC1);
}



ADC扫描模式+DMA
在这里插入图片描述

#include "ADC.h"
uint16_t AD_value[] = {0,0,0,0};

void AD_Init(void)
{
	//开启对应时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
	//GPIO初始化
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed  =  GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	
	//配置ADC的通道配置
	ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1,ADC_Channel_1,2,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1,ADC_Channel_2,3,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1,ADC_Channel_3,4,ADC_SampleTime_55Cycles5);
	
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
	ADC_InitStructure.ADC_NbrOfChannel = 4;
	ADC_InitStructure.ADC_ScanConvMode = ENABLE;
	ADC_Init(ADC1,&ADC_InitStructure);
	
		
	
	DMA_InitTypeDef DMA_InitStructure;
	DMA_InitStructure.DMA_BufferSize = 4;
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//传输方向
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//触发方式
	DMA_InitStructure.DMA_MemoryBaseAddr = (uint16_t)AD_value;//目标地址
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//字节
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//是否自动重装
	DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;//源地址
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//地址是否递增
	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//优先级
	DMA_Init(DMA1_Channel1,&DMA_InitStructure);
	
	DMA_Cmd(DMA1_Channel1,ENABLE);
	ADC_DMACmd(ADC1,ENABLE);
	ADC_Cmd(ADC1,ENABLE);
	
	//ADC校准
	ADC_ResetCalibration(ADC1);//重置所选ADC校准寄存器。
	while(ADC_GetResetCalibrationStatus(ADC1) == SET);//获取所选ADC重置校准寄存器的状态,重置完成硬件清零
	
	ADC_StartCalibration(ADC1);
	while(ADC_GetCalibrationStatus(ADC1) == SET);//获取所选ADC校准状态,校准完成后硬件清零
}


uint16_t AD_GetValue(void)//单通道
{
	DMA_Cmd(DMA1_Channel1,DISABLE);
	DMA_SetCurrDataCounter(DMA1_Channel1,4);
	DMA_Cmd(DMA1_Channel1,ENABLE);
	
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);//ADC软件触发启动转换。
	
	while(DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET);
	DMA_ClearFlag(DMA1_FLAG_TC1);
}


uint16_t AD_GetAppointValue(uint8_t ADC_Channel)//指定通道
{
	
	ADC_RegularChannelConfig(ADC1,ADC_Channel,1,ADC_SampleTime_55Cycles5);
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);//ADC软件触发启动转换。
	while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);
	return ADC_GetConversionValue(ADC1);
}


uint16_t AD_GetVoltage(void)
{
	
	return (AD_GetValue()/4095)*3.3*100;
}








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

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

相关文章

在Centos环境中搭建Nginx环境

一、Nginx概念简介 Nginx是一个轻量级的高性能HTTP反向代理服务器,同时它也是一个通用类型的代理服务器,支持绝大部分协议,如TCP、UDP、SMTP、HTTPS等。 Nginx与redis相同,都是基于多路复用模型构建出的产物,因此它与R…

​docker复现Nginx配置漏洞​

目录 1.docker环境搭建 2.复现过程 2.1CRLF(carriage return/line feed)注入漏洞 ​编辑 2.2.目录穿越 2.3.add_header覆盖 1.docker环境搭建 1.安装docker Debian系列 apt-get update apt-get install docker.io Redhat系列 yum install docker.io 2.下载并解压dock…

无涯教程-Perl - link函数

描述 此函数创建一个新文件名NEWFILE,链接到文件OLDFILE。该函数创建一个硬链接;如果需要符号链接,请使用符号链接功能。 语法 以下是此函数的简单语法- link OLDFILE,NEWFILE返回值 如果失败,此函数返回0,如果成功,则返回1。 例 以下是显示其基本用法的示例…

win10 安装ubuntu子系统并安装宝塔

1、安装子系统 2、ubuntu 中安装宝塔 这里需要注意的: 大部分文章上写的是“面板账户登录信息”不能直接访问,要改成127.0.0.1:8888去访问。 这种情况适合“面板账户登录信息”端口就是8888。 想我的就是32757 这时你就要用 http://127.0.0…

[保研/考研机试] KY183 素数 北京航空航天大学复试上机题 C++实现

题目链接&#xff1a; 素数https://www.nowcoder.com/share/jump/437195121691718444910 描述 输入一个整数n(2<n<10000)&#xff0c;要求输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数&#xff0c;如果没有则输出-1。 输入描述&#xff1a; 输入有多…

HTTP协议超级详解

目录 计算机网络通信 什么是通信协议 协议的标准化 TCP/IP协议群 : 什么是TCP/IP协议群 什么是应用协议 什么是传输协议 什么是网际协议 服务端口 端口作用 端口分配 常见的应用层协议与端口分配 数据包与处理流程 HTTP协议简介 HTTP协议介绍 HTTP协议发展和版…

桂林小程序https证书

现在很多APP都相继推出了小程序&#xff0c;比如微信小程序、百度小程序等&#xff0c;这些小程序的功能也越来越复杂&#xff0c;不可避免的和网站一样会传输数据&#xff0c;因此小程序想要上线就要保证信息传输的安全性&#xff0c;也就是说各种类型的小程序也需要部署https…

什么是BitTorrent协议?

BitTorrent 是一个 P2P (Peer-to-Peer) 通信协议&#xff0c;它设计用于分发数据和电子文件在互联网上。BitTorrent 是目前世界上最流行的 P2P 文件共享协议之一&#xff0c;以下是对 BitTorrent 协议的详细解释&#xff1a; 种子和对等体&#xff1a; 种子&#xff08;Torrent…

【Spring Boot】构建RESTful服务 — 使用Swagger生成Web API文档

使用Swagger生成Web API文档 高质量的API文档在系统开发的过程中非常重要。本节介绍什么是Swagger&#xff0c;如何在Spring Boot项目中集成Swagger构建RESTful API文档&#xff0c;以及为Swagger配置Token等通用参数。 1.什么是Swagger Swagger是一个规范和完整的框架&…

3.2 Tomcat基础

1. Tomcat概述 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器&#xff0c;属于轻量级应用服务器。 Tomcat版本&#xff1a;apache-tomcat-8.5.76。 2.IDEA集成Tomcat 第一步 第二步 第三步 ​ 编辑切换为居中 添加图片注释&#xff0c;不超过 140 字&#xff0…

nodejs+vue+elementui,图书评论管理系统_g9e3a

用户的功能主要是对首页、图书信息、公告信息、在线咨询、个人中心等进行操作。表名&#xff1a;token语言 node.js 框架&#xff1a;Express 前端:Vue.js 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat 开发软件&#xff1a;VScode 前端nodejsvueelementui, 管理员…

绿盟sas安全审计系统任意文件读取漏洞

绿盟sas安全审计系统任意文件读取漏洞 一、产品简介二、漏洞概述三、影响范围四、复现环境POC小龙检测工具: 五、修复建议 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失…

022 - STM32学习笔记 - 扩展外部SDRAM(一) - 初识SDRAM和FMC

022 - STM32学习笔记 - 扩展外部SDRAM&#xff08;一&#xff09; - 初识SDRAM和FMC 之前学习了I2C读写EEPROM和SPI读写FLASH&#xff0c;学完之后在学习一种新的存储介质–SDRAM。 一、初识SDRAM 我们知道在stm32内部是有一定大小的SRAM&#xff08;256Kb&#xff09;和FLA…

C语言案例 分数列求和-11

题目&#xff1a;有一分数列&#xff1a;2 / 1,3 / 2,5 / 3,8 / 5,13 / 8,21 / 13 …求出这个数列的前20项之和。 程序分析 这是一个典型的分数列数学逻辑题&#xff0c;考究这类题目是需要从已知的条件中找到它们的分布规律 我们把前6荐的分子与分母分别排列出来&#xff0c;…

白帽黑帽与linux安全操作

目录 白帽黑帽 Linux安全 白帽黑帽 白帽&#xff08;White Hat&#xff09;和黑帽&#xff08;Black Hat&#xff09;通常用于描述计算机安全领域中的两种不同角色。白帽黑客通常被认为是合法的安全专家&#xff0c;他们通过合法途径寻找和修复安全漏洞&#xff0c;帮助企业和…

【大数据之Flume】八、Flume 数据流监控

1 Ganglia 的安装与部署 &#xff08;1&#xff09;安装 安装规划&#xff1a; 在hadoop102、103、104安装epel-release&#xff1a; sudo yum -y install epel-release在102安装&#xff1a;web、gmetad、gmod&#xff1a; sudo yum -y install ganglia-gmetad sudo yum -y…

【Java】智慧工地云平台源码-支持私有化部署+硬件设备

智慧工地硬件设备包括&#xff1a;AI识别一体机、智能广播音响、标养箱、塔机黑匣子、升降机黑匣子、吊钩追踪控制设备、扬尘监测设备、喷淋设备。 1.什么是AI危险源识别 AI危险源识别是指基于智能视频分析技术&#xff0c;对视频图像信息进行自动分析识别&#xff0c;以实时监…

cmake扩展(1)——VS+CMake创建Qt项目

创建项目 创建CMakeLists #cmake最低版本 cmake_minimum_required(VERSION 3.10) #项目名 project(regextool)#查找所有*.h,*.ui,*.cpp文件&#xff0c;并存入SOURCES中 file(GLOB SOURCES "*.cpp" "*.ui" "*.h")#开启moc set(CMAKE_AUTOMOC O…

SCAU操作系统知识点之(九)单处理器调度

1、处理器调度的类型–长程&#xff0c;中程&#xff0c;短程 例&#xff1a;作业调度程序从处于_____A______状态的队列中选取适当的作业投入运行。 A. 后备 B. 提交 C. 运行 D. 完成 例&#xff1a;**“选一个进程占用 CPU”**是____A_____的功能。 A. 短程调度 B. 中程调度 …

重要日期提醒软件有哪些?有没有适合提醒自己的软件

在时间如潮水般流逝的时代&#xff0c;我们总是在忙碌中度过日子。然而&#xff0c;纵使再忙碌&#xff0c;我们也不能忘记那些温馨而重要的日期&#xff0c;因为这些日期是我们生活中最珍贵的记忆。 无论是生日、纪念日还是重要节日&#xff0c;这些日期都是我们生活的点滴&a…