stm32AD单通道与多通道转换(DMA)

2023-11-09

第三章AD转换

本章的内容分两部分,第一是AD的单通道转换,第二是AD的多通道转换。首先先将单通道转换。

STM32中自带的AD最大的转换频率是14MHZ,共有16个转换通道,每个转

ADC123_IN10表明PC0管脚可以作为AD1,AD2,AD3的第10通道。

下面我们将PC0配置成AD1的通道10为例进行讲解。

3.1首先我们应将PC0设置成模拟输入:

#include "adc.h"

/*为何定义ADC1_DR_Address 为((u32)0x40012400+0x4c)

,因为存放AD转换结果的寄存器的地址就是0x4001244c*/

#define ADC1_DR_Address ((u32)0x40012400+0x4c)

/*定义变量ADC_ConvertedValue,放AD1通道10转换的数据*/

__IO uint16_t ADC_ConvertedValue;

static void ADC1_GPIO_Config(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

/* Enable ADC1 and GPIOC clock */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1

RCC_APB2Periph_GPIOC,ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 ;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

GPIO_Init(GPIOC, &GPIO_InitStructure);

}

|

3.2设置完端口后下一步当然是对AD进行初始化:

这里需要补充一个知识点DMA,DMA就相当与CPU的一个秘书,他的作用就是帮CPU减轻负担的。说的再具体点就是帮CPU来转移数据的。我们都知道,AD每次转换结束后会将转换的结果放到一个固定的寄存器里,以往我们如果想将该寄存器中的值赋给某一变量时会用到赋值语句,如果不用DMA,则赋值语句便要CPU来完成,CPU本来就要忙着处理其他事情,现在还要来解决赋值语句这么简单的问题,肯到会蛋疼。所以需要DMA这个秘书来帮他解决这个问题。由于DMA只是个秘书,所以比较笨,你只有把任务交代清楚了她才能很好的完成任务。那么怎样来给DMA吩咐任务呢,聪明的人肯定想到了,那当然是“DMA_Init(DMA1_Channel1, &DMA_InitStructure)”这个函数啦。下面就来一步步的来给DMA交代任务。

/* 函数名:ADC1_Mode_Config

* 描述 :配置ADC1的工作模式为MDA模式

* 输入 : 无

* 输出 :无

* 调用 :内部调用

*/

static void ADC1_Mode_Config(void)

{

DMA_InitTypeDef DMA_InitStructure;

ADC_InitTypeDef ADC_InitStructure;

/* 将与DMA有关的寄存器设我初始值 */

DMA_DeInit(DMA1_Channel1);

/*定义DMA外设基地址, 这里的ADC1_DR_Address 是用户自己定义的,即为存放转换结果的寄存器 ,他的作用就是告诉DMA取数就到ADC1_DR_Address 这里来取。*/

DMA_InitStructure.DMA_PeripheralBaseAddr =ADC1_DR_Address;

/*定义内存基地址,即告诉DMA要将从AD中取来的数放到ADC_ConvertedValue中 */

DMA_InitStructure.DMA_MemoryBaseAddr =(u32)&ADC_ConvertedValue;

/*定义AD外设作为数据传输的来源,即告诉DMA是将AD中的数据取出放到内存中,不能反过来*/

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

/*指定DMA通道的DMA缓存的大小,即告诉DMA开辟几个内存空间,由于我们只取通道10的AD数据所以只需开辟一个内存空间*/

DMA_InitStructure.DMA_BufferSize = 1;

/*设定寄存器地址固定,即告诉DMA,只从固定的一个地方取数*/

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

/*设定内存地址固定,即每次DMA,,只将数搬到固定的内存中*/

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

/*设定外设数据宽度,即告诉DMA要取的数的大小*/

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

/*设定内存的的宽度*/

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

/*设定DMA工作再循环缓存模式,即告诉DMA要不停的搬运,不能偷懒*/ DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

/*设定DMA选定的通道软件优先级*/

DMA_InitStructure.DMA_Priority = DMA_Priority_High;

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

DMA_Init(DMA1_Channel1, &DMA_InitStructure);

/* Enable DMA channel1,CPU有好几个DMA秘书,现在只用 DMA1_Channel1

这个秘书*/

DMA_Cmd(DMA1_Channel1, ENABLE);

/*设置ADC工作在独立模式*/

ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;

/*规定AD转换工作在单次模式,即对一个通道采样*/

ADC_InitStructure.ADC_ScanConvMode = DISABLE ;

/*设定AD转化在连续模式*/

ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

/*不使用外部促发转换*/

ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; /*采集的数据在寄存器中以右对齐的方式存放*/

ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

/*设定要转换的AD通道数目*/

ADC_InitStructure.ADC_NbrOfChannel = 1;

ADC_Init(ADC1, &ADC_InitStructure);

/*配置ADC时钟,为PCLK2的8分频,即9MHz*/

RCC_ADCCLKConfig(RCC_PCLK2_Div8);

/*配置ADC1的通道11为55.5个采样周期 */

ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_55Cycles5);

/* Enable ADC1 DMA */

ADC_DMACmd(ADC1, ENABLE);

/* Enable ADC1 */

ADC_Cmd(ADC1, ENABLE);

/*复位校准寄存器 */

ADC_ResetCalibration(ADC1);

/*等待校准寄存器复位完成 */

while(ADC_GetResetCalibrationStatus(ADC1));

/* ADC校准 */

ADC_StartCalibration(ADC1);

/* 等待校准完成*/

while(ADC_GetCalibrationStatus(ADC1));

/* 由于没有采用外部触发,所以使用软件触发ADC转换 */

ADC_SoftwareStartConvCmd(ADC1, ENABLE);

}

配置完以上的程序,那么AD每转换一次,DMA都会将转换结果搬到变量

ADC_ConvertedValue中,而不需用每次都用赋值语句来取值AD转换的值。

第二部分:AD多路采样

#include "adc.h"

#define ADC1_DR_Address ((u32)0x40012400+0x4c)

/*定义数组变量ADC_ConvertedValue[2],分别放AD1通道10和11转换的数据*/

__IO uint16_t ADC_ConvertedValue[2];

/*

* 函数名:ADC1_GPIO_Config

* 描述 :使能ADC1和DMA1的时钟,设置PC0,PC1为模拟输入

* 输入 : 无

* 输出 :无

* 调用 :内部调用

*/

static void ADC1_GPIO_Config(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

/* Enable DMA clock */

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

/* Enable ADC1 and GPIOC clock */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC,ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

GPIO_Init(GPIOC, &GPIO_InitStructure);

}

/* 函数名:ADC1_Mode_Config

* 描述 :配置ADC1的工作模式为MDA模式

* 输入 : 无

* 输出 :无

* 调用 :内部调用

*/

static void ADC1_Mode_Config(void)

{

DMA_InitTypeDef DMA_InitStructure;

ADC_InitTypeDef ADC_InitStructure;

/* DMA channel1 configuration */

DMA_DeInit(DMA1_Channel1);

/*定义DMA外设基地址,即为存放转换结果的寄存器*/

DMA_InitStructure.DMA_PeripheralBaseAddr =ADC1_DR_Address; /*定义内存基地址*/

DMA_InitStructure.DMA_MemoryBaseAddr

=(u32)&ADC_ConvertedValue;

/*定义AD外设作为数据传输的来源*/

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

/*指定DMA通道的DMA缓存的大小,即需要开辟几个内存空间,本实验有两个转换通道,所以开辟两个*/

DMA_InitStructure.DMA_BufferSize = 2;

/*设定寄存器地址固定*/

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; /*设定内存地址递加,即每次DMA都是将该外设寄存器中的值传到两个内存空间中*/

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /*设定外设数据宽度*/

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

/*设定内存的的宽度*/

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

/*设定DMA工作再循环缓存模式*/

DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

/*设定DMA选定的通道软件优先级*/

DMA_InitStructure.DMA_Priority = DMA_Priority_High;

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

DMA_Init(DMA1_Channel1, &DMA_InitStructure);

/* Enable DMA channel1 */

DMA_Cmd(DMA1_Channel1, ENABLE);

/*设置ADC工作在独立模式*/

ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;

/*规定AD转换工作在扫描模式,即对多个通道采样*/ ADC_InitStructure.ADC_ScanConvMode = ENABLE ;

/*设定AD转化在连续模式*/

ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

/*不使用外部促发转换*/

ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

/*采集的数据在寄存器中以右对齐的方式存放*/

ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

/*设定要转换的AD通道数目*/

ADC_InitStructure.ADC_NbrOfChannel = 2;

ADC_Init(ADC1, &ADC_InitStructure);

/*配置ADC时钟,为PCLK2的8分频,即9MHz*/

RCC_ADCCLKConfig(RCC_PCLK2_Div8);

/*配置ADC1的通道10和11的转换先后顺序以及采样时间为为55.5个采样周期 */

ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_55Cycles5);

ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_55Cycles5);

/* Enable ADC1 DMA */

ADC_DMACmd(ADC1, ENABLE);

/* Enable ADC1 */

ADC_Cmd(ADC1, ENABLE);

/*复位校准寄存器 */

ADC_ResetCalibration(ADC1);

/*等待校准寄存器复位完成 */

while(ADC_GetResetCalibrationStatus(ADC1));

/* ADC校准 */

ADC_StartCalibration(ADC1);

/* 等待校准完成*/

while(ADC_GetCalibrationStatus(ADC1));

/* 由于没有采用外部触发,所以使用软件触发ADC转换 */

ADC_SoftwareStartConvCmd(ADC1, ENABLE);

}

!!!!!单通道采样与多通道采样的不同点都在

第二段程序中用红色标出来了,注意比较。

总结:DMA就是一个无私奉献的搬运工,想将外设寄存器中的值放入内存中原本需要CPU来完成,现在DMA来帮CPU完成,这在一定程度上解放了CPU.



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

stm32AD单通道与多通道转换(DMA) 的相关文章

  • Parameter 0 of constructor in XXX required a single bean, but 3 were found:

    原因 因为在构造函数中 需要一个单一的 OrderStatus Bean 但Spring在容器中找到了三个这样的Bean 解决方式 在随机一个组件中加入一个注解 Primary Component Primary Slf4j public
  • 18650锂电池参数、充放电时间计算详解

    我们以NCR18650B举例 其参数为 额定容量 3200mAh 容量范围3250mAh 3350mAh 额定电压 3 6V 充电参数 恒流 恒压 充电电流为1625mA 充电到4 2V 需要4小时 质量 48 5g 充电温度 放电温度 存
  • 傅里叶变换公式及其推导【超详细!】

    题主本硕机械专业 自学转互联网 算法岗成功 获得阿里 字节 美团 华为等 15 offer 后续会在公众号 苏学算法 分享各类学习笔记 面试经验 感兴趣的可以关注一波 一 核心公式 时域 gt gt gt 频域 X
  • idea 类注释模板

    类注释模板如下 if PACKAGE NAME PACKAGE NAME package PACKAGE NAME end parse File Header java ClassName NAME Author name Date DAT
  • K8S 部署 SpringBoot 项目(一篇够用)

    现在比较多的互联网公司都在尝试将微服务迁到云上 这样的能够通过一些成熟的云容器管理平台更为方便地管理微服务集群 从而提高微服务的稳定性 同时也能较好地提升团队开发效率 但是迁云存在一定的技术难点 今天这篇文章主要介绍如何从0开始搭建一套基于
  • c语言程序设计

    一 c语言主要特点 1 语法设计不 太严格 软件程序自由度大 2 对变量的类型使用比较灵活 如整型和字符型数据可以通用 3 c语言具有高级语言的功能和低级语言的很多功能 可以用来编写系统软件 4 编译系统简洁 易移植等特点 例如 inclu
  • 360云盘会不会停止服务器,360云盘能否继续使用啊?

    2017 10 10 03 56 14 除非你已购买了企业云盘只要交了费就可以使用了 可用原云盘帐号登录 把原云盘内的数据一键导入企业云盘 全部 2017 10 10 03 56 14 2017 10 10 03 56 14 完善个人资料
  • Redis单机最大并发量

    redis单机最大并发量 布隆过滤器 多级缓存 客户端缓存 应用层缓存 Expires和Cache Control的区别 Nginx缓存管理 服务层缓存 进程内缓存 进程外缓存 缓存数据一致性问题的解决 引入多级缓存设计的时刻 Redis的
  • sentinelsat包介绍

    这次主要介绍sentinelsat包 包括查询条件和相关的API等 主要记录自己学习过程 首先我们需要知道欧空局ESA的数据 因为考虑数据存储等问题 会将sentinel数据从在线存档中删除 对于长期存档的数据 会出现offline情况 在
  • 编程常用英语词汇

    按字母索引 A 开头 B 开头 C 开头 D 开头 E 开头 F 开头 G 开头 H 开头 I 开头 J 开头 K 开头 L 开头 M 开头 N 开头 O 开头 P 开头 Q 开头 R 开头 S 开头 T 开头 U 开头 V 开头 W 开头
  • PHP preg_replace() 正则替换所有符合条件的字符串

    PHP preg replace 正则替换 与Javascript 正则替换不同 PHP preg replace 默认就是替换所有符号匹配条件的元素 需要我们用程序处理的数据并不总是预先以数据库思维设计的 或者说是无法用数据库的结构去存储
  • Flutter 修改默认生成的 minSdkVersion

    Flutter 修改默认生成的 minSdkVersion 问题 flutter pub get 会自动生成 android 目录 但是如果要修改 build gradle 文件里面的内容 需要每次都要手动改一下 很麻烦 解决办法 修改 f
  • 大数据毕设项目 opencv 图像识别 指纹识别 - python

    文章目录 0 前言 1 课题背景 2 效果展示 3 具体实现 3 1 图像对比过滤 3 2 图像二值化 3 3 图像侵蚀细化 3 4 图像增强 3 5 特征点检测 4 OpenCV 0 前言 这两年开始毕业设计和毕业答辩的要求和难度不断提升
  • 【动手学习pytorch笔记】33.Attention实现

    Attention实现 import math import torch from torch import nn from d2l import torch as d2l 带掩码的softmax 有些query是不应该看到后面的key的
  • glslViewer 介绍 (001)

    GitHub patriciogonzalezvivo glslViewer Console based GLSL Sandbox for 2D 3D shaders 起个头先 把官网的windows安装过程 step by step 化
  • unity实现mmd功能(跳舞)

    将pmx模型转化为fbx模型 将fbx模型导入 在对应的Inspector面板上的四个勾选打勾并Apply应用一下 在接下来弹出的界面中将vmd动画拖入到对应的Object栏中并点击生成相应动画的模型 vmd动画的制作 新建一个动画状态机控
  • 1.Windows环境配置

    1 做逆向Linux系统比Windows系统问题少的原因 Windows版本种类过多 Windows使用的编码不一样 2 电脑系统版本 原版Windows10即可 运行winver可查看系统版本 推荐版本 Windows10 专业版 20H
  • Hibernate-validator数据验证

    前言 数据效验工作在开发工作中 是非常重要的 保证数据的正确性 可靠性 安全性 不仅在前端进行效验 还要在后台继续进行效验 前端做验证只是为了用户体验 比如控制按钮的显示隐藏 单页应用的路由跳转等等 后端才是最终的保障 总之 一切用户的输入
  • opencv4.6 报错 error: ‘cv::xfeatures2d::SIFT’ has not been declared

    opencv4 6报错error cv xfeatures2d SIFT has not been declared SIFT 已经由 xfeatures2d 移至 主仓库 cv xfeatures2d SIFT create 改为 cv

随机推荐

  • 如何用一行 Python 代码实现并行

    前言 Python 在程序并行化方面多少有些声名狼藉 撇开技术上的问题 例如线程的实现和 GIL 我觉得错误的教学指导才是主要问 题 常见的经典 Python 多线程 多进程教程多显得偏 重 而且往往隔靴搔痒 没有深入探讨日常工作中最有用的
  • widows家庭版没有Hyper-v的解决方式

    首先这个是我在安装docker的时候遇到的问题 下面记录一下 复制下面代码到一个文本文件中去 然后修改后缀名为cmd然后运行即可 pushd dp0 dir b SystemRoot servicing Packages Hyper V m
  • jQuery.extend 函数详解

    转载自 http www cnblogs com RascallySnake archive 2010 05 07 1729563 html jQuery extend 函数详解 jQuery 的 extend 扩展方法 jQuery 的扩
  • 【构建ML驱动的应用程序】第 1 章 :从产品目标到 ML 框架

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • 光耦电路

    光电耦合器 opticalcoupler 英文缩写为OC 亦称光电隔离器或光耦合器 简称光耦 它是以光为媒介来传输电信号的器件 通常把发光器 红外线发光二极管LED 与受光器 光敏半导体管 封装在同一管壳内 当输入端加电信号时发光二极管发出
  • python 实现 soap 请求

    1 什么是soap SOAP Simple Object Access Protocol 是一种基于XML的通信协议 用于在网络上交换结构化的和可扩展的信息 它被广泛用于分布式系统中的应用程序之间的通信 SOAP通过HTTP 或其他传输协议
  • AI绘画爆火背后:扩散模型(Diffusion Model)原理综述

    来源 知乎 大仲马 地址 https zhuanlan zhihu com p 562389931 本综述 Diffusion Models A Comprehensive Survey of Methods and Application
  • Linux下TCP通信时如果一方拔掉网线会怎么样?

    本文95 参考下面的链接 拔掉网线后 原本的 TCP 连接还存在吗 TCP协议 长连接和短连接 如果没有数据传输 不能被TCP感知到 TCP连接状态依旧保持 如果有数据传输 重传次数超过一定值 Linux下默认15 或超过一定的 超时时间则
  • 笔试

    文章目录 前言 1 什么叫FPGA 2 什么叫数字IC 3 FPGA设计流程 3 1系统规划 3 2RTL输入 3 3行为仿真 功能仿真 3 4逻辑综合 3 5综合后仿真 可选 3 6综合后设计分析 时序及资源 3 7设计实现 包括布局布线
  • 1024 祝我们快乐

    1024 祝我们快乐 前言 最近好久都很忙 所以没有在发过文章啦 但是今天这么激动的日子 还是忍不住想要祝你们快乐哈 感谢很多人的默默陪伴 比如平台 展现量直接上万 比如 你们 超级感谢 很感激你们的支持 虽说我不是最优秀的那一个 但是你们
  • spring 容器(控制反转及依赖注入)

    spring 是一个容器 项目开始就一直在运行 spring 加载进内存里面 容器中有监听器 引入容器 而struts注重运行时 核心类中监听器 监听启动后可以从context 上下文即spring所有的配置 中获取内容 将核心配置文件 a
  • 将本地的txt文件上传到mysql数据库中

    我的数据 1 将windows中的txt文件传入到Linux中 2 在mysql中将表创建好 例如 create table users userid int time date id int sex varchar 10 birthday
  • .NET 各种框架

    基于 NET平台常用的框架整理 分布式缓存框架 Microsoft Velocity 微软自家分布式缓存服务框架 Memcahed 一套分布式的高速缓存系统 目前被许多网站使用以提升网站的访问速度 Redis 是一个高性能的KV数据库 它的
  • No.87-HackTheBox-windows-Bankrobber-Walkthrough渗透学习

    HackTheBox windows Bankrobber Walkthrough 靶机地址 https www hackthebox eu home machines profile 209 靶机难度 初级 3 2 10 靶机发布日期 2
  • 神经网络主要有三个基本要素:权重、偏置和激活函数

    神经网络主要有三个基本要素 权重 偏置和激活函数 权重 神经元之间的连接强度由权重表示 权重的大小表示可能性的大小 偏置 偏置的设置是为了正确分类样本 是模型中一个重要的参数 相当于加入一个常数 激活函数 起非线性映射的作用 其可将神经元的
  • 数据结构与算法(C语言)

    第一章 数据结构绪论 1 什么是程序 程序 数据结构 算法 2 逻辑结构 物理结构的区别用法 基本的目标就是将数据及其逻辑关系存储到计算机的内存中 一 逻辑结构 逻辑结构是指数据对象中数据元素之间的相互关系 逻辑结构是面向问题的 A 集合结
  • 新手入门Linux-Ubuntu20.04

    打开此文 首先祝你在使用Linux过程中如鱼得水 其次 如果是为了检验DIY 装 能力 X 请耐心观看 如果是想有一个很奈斯的环境去写代码 请移步Deepin 国产Deepin也日渐成熟且UI很不错 一 配置基础的设置 设置自动登录 设置T
  • MATLAB实现多元线性回归

    function b bint r rint stats Multiple linear regression X y alpha Multiple linear regression 多元线性回归 对于输入数据 必须是去除量纲之后的数据
  • 【linux】linux shell 判断是安装了某个软件

    1 概述 判断是否安装了node if type node gt dev null 2 gt 1 then echo node 未安装 else echo node 已安装 fi 判断是否安装了npm if type npm gt dev
  • stm32AD单通道与多通道转换(DMA)

    第三章AD转换 本章的内容分两部分 第一是AD的单通道转换 第二是AD的多通道转换 首先先将单通道转换 STM32中自带的AD最大的转换频率是14MHZ 共有16个转换通道 每个转 ADC123 IN10表明PC0管脚可以作为AD1 AD2