STM32CubeMX教程15 ADC - 多重ADC转换
1、准备材料
STM32CubeMX软件(Version 6.10.0)
keil µVision5 IDE(MDK-Arm)
3个滑动变阻器
2、实验目标
使用STM32CubeMX软件配置STM32F407开发板的ADC实现多重ADC采集,具体为使用ADC1_IN5、ADC2_IN6实现二重ADC采集,使用ADC1_IN5、ADC2_IN6和ADC3_IN5实现三重ADC采集
3、二重ADC转换
3.0、前提知识
STM32F407的三个ADC可以组合实现多重ADC采集,当仅仅开启一个ADC时,该ADC只能工作在独立模式;当同时启动ADC1和ADC2,则以ADC1为主器件,ADC2为从器件可以工作在双重ADC采集模式下;当同时启动ADC1/2/3,则以ADC1为主器件,ADC2/3为从器件可以工作在三重ADC采集模式下;
在多重 ADC 模式下可实现以下6种模式
- 二/三重注入同时模式 + 规则同时模式
- 二/三重规则同时模式 + 交替触发模式
- 二/三重注入同时模式
- 二/三重规则同时模式
- 二/三重交替模式
- 二/三重交替触发模式
本实验我们只介绍二/三重规则同时模式,如下图所示为CubeMX配置中可选的所有模式

工作在多重ADC模式下的DMA请求拥有三种DMA模式,这里只介绍DMA access mode 1/2,不会涉及DMA access mode 3
二重规则同时模式ADC采集时只能选择DMA access mode 2,三重规则同时模式ADC采集时只能选择DMA access mode 1
下面请读者重点理解采集完成的数据是如何通过DMA存入用户定义好的数组中的!
当ADC工作在二重规则同时模式下,此时DMA模式为DMA access mode 2,在ADC1或ADC2转换事件结束时,会生成一个32位DMA传输请求,此请求会将存储在 ADC_CDR 32 位寄存器高位半字中的 ADC2 转换数据传输到SRAM,然后将存储在ADC_CCR低位半字中的ADC1转换数据传输到 SRAM,也就是说我们只需定义一个包含一个元素的uint32_t DataBuffer[1]数组,以DMA方式启动ADC转换后,只需每次从高16位读取ADC2采集的数据,从低16位读取ADC1采集的数据即可
当ADC工作在三重规则同时模式下,此时DMA模式为DMA access mode 1,在ADC1、ADC2或ADC3转换事件结束时,会生成三个32位DMA传输请求,之后会发生三次从 ADC_CDR 32 位寄存器到SRAM的传输:首先传输 ADC1 转换数据,然后是 ADC2 转换数据,最后是 ADC3 转换数据,也就是说我们需定义一个包含三个元素的uint32_t DataBuffer[3]数组,其中第一个元素DataBuffer[0]表示ADC1采集的数据,第二个元素DataBuffer[1]表示ADC2采集的数据,第三个元素DataBuffer[2]表示ADC3采集的数据
上述描述如下图所示 (注释1)



如下图所示为多重ADC框图,当工作在二重ADC时不存在ADC3,ADC1/2/3三个ADC只有ADC1为主ADC,当以多重ADC工作时,只需要配置主ADC的DMA传输,从ADC无需设置,在启动多重ADC采集时也只能以DMA方式启动主ADC,从ADC以普通方式启动即可,不能将从ADC也以DMA方式启动,多重ADC采集的数据均会存入32位的通用规则数据寄存器中

3.1、CubeMX相关配置
3.1.0、工程基本配置
打开STM32CubeMX软件,单击ACCESS TO MCU SELECTOR选择开发板MCU(选择你使用开发板的主控MCU型号),选中MCU型号后单击页面右上角Start Project开始工程,具体如下图所示


开始工程之后在配置主页面System Core/RCC中配置HSE/LSE晶振,在System Core/SYS中配置Debug模式,具体如下图所示


详细工程建立内容读者可以阅读“STM32CubeMX教程1 工程建立”
3.1.1、时钟树配置
系统时钟使用8MHz外部高速时钟HSE,HCLK、PCLK1和PCLK2均设置为STM32F407能达到的最高时钟频率,具体如下图所示

3.1.2、外设参数配置
本实验需要需要初始化USART1作为输出信息渠道,具体配置步骤请阅读“STM32CubeMX教程9 USART/UART 异步通信”
设置TIM3通用定时器溢出时间100ms,外部触发事件选择更新事件,参数详解请阅读“STM32CubeMX教程6 TIM 通用定时器 - 生成PWM波”实验,具体配置如下图所示

在Pinout & Configuration页面左边功能分类栏目Analog中单击其中ADC1,勾选IN5通道
Mode (ADC模式):修改为Dual regular simultaneous mode only(需要启用ADC2通道才可以选择二重ADC采集模式)
DMA Access Mode (DMA模式):选择DMA access mode 2
DMA Continuous Requests (DMA连续转化请求):使能(需要先增加DMA请求才可以使能)
其他参数与“STM32CubeMX教程13 ADC - 单通道转换”实验均保持一致,具体配置如下图所示

单击Configuration中的DMA Settings选项卡对ADC1的DMA请求进行设置,所有配置均与“STM32CubeMX教程14 ADC - 多通道DMA转换”实验保持一致,具体配置如下图所示

在Pinout & Configuration页面左边功能分类栏目Analog中单击其中ADC2,勾选IN6通道,注意除 Rank 和 DMA Continuous Requests 参数外所有参数配置必须与ADC1保持一致,否则ADC采集将出现错误,具体配置如下图所示

3.1.3、外设中断配置
在Pinout & Configuration页面左边System Core/NVIC中勾选DMA2 Stream0 全局中断,然后选择合适的中断优先级即可,具体配置如下图所示

3.2、生成代码
3.2.0、配置Project Manager页面
单击进入Project Manager页面,在左边Project分栏中修改工程名称、工程目录和工具链,然后在Code Generator中勾选“Gnerate peripheral initialization as a pair of 'c/h' files per peripheral”,最后单击页面右上角GENERATE CODE生成工程,具体如下图所示


详细Project Manager配置内容读者可以阅读“STM32CubeMX教程1 工程建立”实验3.4.3小节
3.2.1、外设初始化调用流程
请阅读“STM32CubeMX教程14 ADC - 多通道DMA转换”实验“3.2.1、外设初始化调用流程”小节
3.2.2、外设中断调用流程
请阅读“STM32CubeMX教程14 ADC - 多通道DMA转换”实验“3.2.2、外设中断调用流程”小节
3.2.3、添加其他必要代码
在adc.c中重新实现ADC转换完成回调函数HAL_ADC_ConvCpltCallback(),具体代码如下所示
源代码如下
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
/*定时器中断启动DMA二重ADC转换*/
uint32_t Volt1,Volt2;
uint32_t adcValue=DataBuffer[0];
/*从低16位取出ADC1采集数据*/
uint32_t ADC1_val=adcValue & 0x0000FFFF;
Volt1=3300*ADC1_val;
Volt1=Volt1>>12;
/*从高16位取出ADC2采集数据*/
uint32_t ADC2_val=adcValue & 0xFFFF0000;
ADC2_val= ADC2_val>>16;
Volt2=3300*ADC2_val;
Volt2=Volt2>>12;
printf("Volt1:%d, Volt2:%d\r\n",Volt1,Volt2);
}
在主函数main中启动二重ADC转化,一些全局变量定义及启动源代码如下
/*main.c全局变量定义*/
uint32_t DataBuffer[BATCH_DATA_LEN];
/*main.h变量声明*/
#define BATCH_DATA_LEN 1
extern uint32_t DataBuffer[BATCH_DATA_LEN];
/*ADC启动代码*/
HAL_ADC_Start(&hadc2);
HAL_ADCEx_MultiModeStart_DMA(&hadc1,DataBuffer,BATCH_DATA_LEN);
HAL_TIM_Base_Start(&htim3);
为什么二重ADC转化下DMA要将数据传输到uint32 DataBuffer[1]?
二重ADC转化下DMA模式为DMA access mode 2,在该模式下ADC1转换完成的数据会传输到32位的 DataBuffer[0] 的低16位,而ADC2转换完成的数据会传输到32位的 DataBuffer[0] 的高16位
4、常用函数
/*多重ADC以DMA方式启动*/
HAL_StatusTypeDef HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef *hadc, uint32_t *pData, uint32_t Length)
5、烧录验证
烧录程序,单片机上电之后,串口不断的输出ADC1_IN5、ADC2_IN6的采集值转化为的电压值,笔者将两个滑动变阻器按照ADC1_IN5、ADC2_IN6的顺序,分别从一端缓慢拧到另一端,可以从串口输出的数据看到,三个通道采集到的电压值从最小值0慢慢变到最大3300

6、三重ADC转换
6.1、CubeMX相关配置
在Pinout & Configuration页面左边功能分类栏目Analog中单击其中ADC3,勾选IN5通道,所有参数与二重ADC转换ADC2参数一致,在配置ADC1为三重ADC规则通道采集时ADC3的触发源参数会消失,因此无需理会,具体ADC3参数配置如下图所示

在Pinout & Configuration页面左边功能分类栏目Analog中单击其中ADC1,将其模式修改为Triple regular simultaneous mode only,DMA模式修改为DMA access mode 1
ADC1的其他参数与二重ADC转换时的参数一致,ADC2的配置、ADC1 DMA的配置和NVIC的设置均与二重ADC采集一致,具体ADC1参数配置如下图所示

6.2、添加其他必要代码
/*main.c全局变量定义*/
uint32_t DataBuffer[BATCH_DATA_LEN];
/*main.h变量声明*/
#define BATCH_DATA_LEN 3
extern uint32_t DataBuffer[BATCH_DATA_LEN];
/*主函数中ADC启动代码*/
HAL_ADC_Start(&hadc2);
HAL_ADC_Start(&hadc3);
HAL_ADCEx_MultiModeStart_DMA(&hadc1,DataBuffer,BATCH_DATA_LEN);
HAL_TIM_Base_Start(&htim3);
/*adc.c中重新实现转换完成中断回调*/
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
/*定时器中断启动DMA三重ADC转换*/
uint32_t val=0,Volt=0;
for(uint8_t i=0;i<BATCH_DATA_LEN;i++)
{
val=DataBuffer[i];
Volt=(3300*val)>>12;
printf("ADC%d, val:%d, Volt:%d\r\n",i,val,Volt);
}
printf("\r\n");
}
为什么三重ADC转化下DMA要将数据传输到uint32 DataBuffer[3]?
二重ADC转化下DMA模式为DMA access mode 1,在该模式下ADC1转换完成的数据会传输到32位的 DataBuffer[0],ADC2转换完成的数据会传输到32位的 DataBuffer[1],ADC3转换完成的数据会传输到32位的 DataBuffer[2]
6.3、实验现象
烧录程序,单片机上电之后,串口不断的输出ADC1_IN5、ADC2_IN6和ADC3_IN5的采集值,笔者将三个滑动变阻器按照ADC1_IN5、ADC2_IN6和ADC3_IN5的顺序,分别从一端缓慢拧到另一端,可以从串口输出的数据看到,三个通道采集到的ADC数据从最小值0慢慢变到最大4095

7、注释详解
注释1:图片来源STM32F4xx中文参考手册
8、参考资料
主要参考STM32Cube高效开发教程(基础篇)320页14.6小节实验
笔者认为该章节提到一个BUG其实是错误的,从ADC不应该以DMA方式启动,也无需在STM32CubeMX生成的工程代码中手动修改DMAContinuousRequests为ENABLE


更多内容请浏览 STM32CubeMX+STM32F4系列教程文章汇总贴
STM32CubeMX教程15 ADC - 多重ADC转换的更多相关文章
- STM32使用HAL库实现ADC单通道转换
STM32的ADC转换还是很强大的,它具有多个通道选择,这里我就不细说,不了解的可以自行百度,这里只是选取单通道,实现ADC转换.在文章开始之前,我说一下数据左对齐跟右对齐的差别,以前一直糊里糊涂的, ...
- stm32 ADC模数转换 ADC多通道 ADC DMA
通过调节电位器,改变AD转换值和电压值 STM32F1 ADC 配置步骤 1.使能GPIO时钟和ADC时钟 2.配置引脚模式为模拟输入 3.配置ADC的分频因子 4.初始化ADC参数,ADC_Init ...
- [译]Vulkan教程(15)图形管道基础之RenderPass
[译]Vulkan教程(15)图形管道基础之RenderPass Render passes Setup 设置 Before we can finish creating the pipeline, ...
- 深度学习与计算机视觉教程(15) | 视觉模型可视化与可解释性(CV通关指南·完结)
作者:韩信子@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/37 本文地址:http://www.showmeai.tech/article-det ...
- [SQL基础教程] 1-5 表的删除和更新
[SQL基础教程] 1-5 表的删除和更新 表的删除 语法 DROP TABLE <表名>; 法则 1-12 删除的表无法恢复 表定义的更新 语法 ALTER TABLE<表名> ...
- [ADC]Linux ADC驱动
ADC TI adc user guide: http://processors.wiki.ti.com/index.php/Linux_Core_ADC_Users_Guide 问题: 在tools ...
- Directx11教程(15) D3D11管线(4)
原文:Directx11教程(15) D3D11管线(4) 本章我们首先了解一下D3D11中的逻辑管线,认识一下管线中每个stage的含义. 参考资料:http://fgiesen.wordpress ...
- 3、CC2541芯片中级教程-OSAL操作系统(ADC光敏电阻和修改串口波特率)
本文根据一周CC2541笔记汇总得来—— 适合概览和知识快速索引—— 全部链接: 中级教程-OSAL操作系统\OSAL操作系统-实验01 OSAL初探 [插入]SourceInsight-工程建立方法 ...
- 玩转X-CTR100 l STM32F4 l ADC 模拟数字转换
我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] 本文介绍X-CTR100控制器 AD转换接 ...
- PaintCode 教程:矢量图轻松转换成CoreGraphics代码
本文译自Ranwenderlich的这篇:http://www.raywenderlich.com/100281/paintcode-for-designers-getting-started Pai ...
随机推荐
- easy ui 按钮图标样式合集
data-options="iconCls:'icon-search'" 可替换以下值 icon-add icon-print icon-mini-add icon-cvs ico ...
- CoreFX中Dictionary<TKey, TValue>的源码解读
无论是实际的项目中,还是在我们学习的过程中,都会重点的应用到Dictionary<TKey, TValue>这个存储类型.每次对Dictionary<TKey, TValue> ...
- 高效使用 PyMongo 进行 MongoDB 查询和插入操作
插入到集合中: 要将记录(在MongoDB中称为文档)插入到集合中,使用insert_one()方法.insert_one()方法的第一个参数是一个包含文档中每个字段的名称和值的字典. import ...
- 平稳扩展:可支持RevenueCat每日12亿次API请求的缓存
平稳扩展:可支持RevenueCat每日12亿次API请求的缓存 目录 平稳扩展:可支持RevenueCat每日12亿次API请求的缓存 低延迟 建立连接池 故障检测 Up and warm 对故障做 ...
- Centos8离线安装golang
一.下载golang 1.下载安装包 2.下载后解压. tar -zxvf go1.17.linux-amd64.tar.gz 二.配置环境变量 vim /etc/profile 1.在环境变量最后添 ...
- 一篇可供参考的 K8S 落地实践经验
前言 k8s 即 Kubernetes,是一个开源的容器编排引擎,用来对容器化应用进行自动化部署. 扩缩和管理 本篇文章将分享 k8s v1.18.8 的安装,以及其面板,监控,部署服务,使用Ingr ...
- iMessage群发,iMessage群发功能,iMessage群发功能设计,iMessage群发系统
在数字通讯时代,群发消息已经成为我们日常生活中不可或缺的一部分,无论是商务.社交还是日常沟通,群发功能都大大提高了消息传递的效率和便利性. 而在众多的通讯软件中,iMessage无疑是其中的佼佼者,今 ...
- linux rz/sz 拖动文件上传
不需要第三方上传文件直接 rz上传 拖动.以及 sz下载文件 多舒服 那么 他来了 安装与使用 yum安装 yum -y install lrzsz 使用上传文件,执行命令rz,会跳出文件选择窗口,选 ...
- 编写.NET的Dockerfile文件构建镜像
创建一个WebApi项目,并且创建一个Dockerfile空文件,添加以下代码,7.0代表的你项目使用的SDK的版本,构建的时候也需要选择好指定的镜像tag FROM mcr.microsoft.co ...
- STM32CubeMX教程10 RTC 实时时钟 - 周期唤醒、闹钟A/B事件和备份寄存器
本实验主要使用STM32CubeMX软件配置STM32F407开发板实现RTC周期唤醒.闹钟A/B事件功能,周期唤醒中输出RTC时间,闹钟A/B事件发生时利用串口输出闹钟A/B事件发生提示 1.准备材 ...