基于DMA的ADC数据采集

简介: 嵌入式系统开发经常会遇到采集模拟量的功能需求,这时就会用到ADC,STM32系列MCU提供了强大的ADC功能,其提供的多通道采集和DMA方式极大的方便了ADC相关的开发流程,本文主要记录一下,如何使用ADC实现基于DMA的多通道模拟量采集功能。

嵌入式系统开发经常会遇到采集模拟量的功能需求,这时就会用到ADC,STM32系列MCU提供了强大的ADC功能,其提供的多通道采集和DMA方式极大的方便了ADC相关的开发流程,本文主要记录一下,如何使用ADC实现基于DMA的多通道模拟量采集功能。

关于ADC的配置,同样可以通过STM32CubeMX来实现,下面是STM32型号和STM32CubeMX的版本信息:


  • MCU:STM32F103C8T6


  • STM32CubeMX:5.5.0


下面是具体的配置步骤


系统基本配置


时钟配置


首先,配置系统时钟,本文基于STM32F103C8T6的一款开发板进行开发,其提供的外部晶振频率为8MHz,所以,对于时钟我们的配置为:


网络异常,图片无法展示
|


下面进行ClockConfiguration相关的配置,第一步选择时钟源为HSE:8MHZ,第二步选择APB2的时钟源为32MHz,最后一步选择ADC1的时钟频率为8MHz,最终的配置结果如下:


网络异常,图片无法展示
|


打开ST-Link调试


对于MCU的程序下载和调试,我们选用的是ST-Link,所以选择系统的调试模式为Serial Wire,配置如下:


网络异常,图片无法展示
|


注:对于通过ST-Link或JTAG下载、调试程序时,需要配置该选项,否则无法下载程序以及在线调试MCU。


配置ADC


功能需求是:


  • 使用ADC1实现模拟量的采集;


  • 两路模拟量采集;


  • 基于DMA实现外设到内存的数据传输;


基本配置


首先是,基本配置选择将要使用的ADC,这里我们使用的是ADC1,其次是选择用于模拟量采集的ADC通道,这里我们选择是ADC1的通道6和通道7,具体配置如下:


网络异常,图片无法展示
|


下面是关于ADC的参数配置,主要分为两部分:第一部分为ADC_Setting,第二部分为ADC_Regular_ConversionMode,下面分别解决一下:


  1. ADC_Setting:


  • Data Alignment:Right alignment。表示ADC的regular data register寄存器16bit数据的对齐方式为向右对齐。


  • Scan Conversion Mode:Enable。当使用DMA采集多路模拟量时,使能该选项可以自动扫描ADC的模拟量数据通道,采集模拟量数据。


  • Continuous Conversion Mode:Enable。使能该项时,可以对各个模拟量通道进行循环、连续的数据采集。


  1. ADC_Regular_ConversionMode:


  • Enable Regular Conversions: Enable。打开Regular数据转换模式。对于Regular Conversion和Injected Conversion两种模式的区别可以简单的理解为:Regular Conversion为轮询采集的工作模式,Injected Conversion为中断采集工作模式,并且Injected Conversion比Regular Conversion的优先级高。


  • Nunber of Conversion:2。表示采集的通道数量。


  • Rank   1:表示第一个采集通道,即通道Channel 7,Sample Time为1.5 Cycles,1个Cycle为ADC驱动时钟频率的倒数,本文为 1 Cycle = 1/8M s。


  • Rank   2:表示第二个采集通道,即通道Channel 6,Sample Time为1.5 Cycles,同上。


网络异常,图片无法展示
|


DMA配置


进入ADC的DMA配置选项,关于ADC的DMA配置方式如下:


  1. 添加DMA Request:添加ADC1为DMA Reuest,Channel为DMA1 Channel 1,DMA的数据传输方向为:peripheral To Memory(外设到内存),Priori为Low。


  1. 配置DMA Requeset Settings:


  • Mode:Circular。表示DMA循环、连续采集各个ADC通道的模拟量。


  • Data Width为Word。表示DMA传输的数据的基本大小为Word,即四字节。


网络异常,图片无法展示
|


好了,配置基本完成了,下面是MCU的PinView,大家可以参考一下。点击Generate Code生成工程代码。


网络异常,图片无法展示
|


功能实现


基于STM32CubeMX生成的代码,完善ADC采集代码,主要就是调用HAL_ADC_Start_DMA启动ADC采集,实现HAL_ADC_ConvCpltCallback接口,当DMA采集完一轮数据之后,会调用该接口通知APP,APP可以在这里完成模拟量的转换功能。


/*其中,pData表示DMA的目标内存地址,Length表示外设向内存传输的数据项的个数。*/
HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length);
/*处理DMA数据*/
uint32_t val[2];//保存外设通过DMA传输的过来的数据
float v[2];//保存当前采集到的模拟量
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
  for(int8_t i = 0; i < 2; i++) {
  v[i] = (val[i] / 4095.0) * 3.274; //参考电压为:3.274V  
}


好了,至此基本完成了基于DMA的ADC采集方式的功能需求。


测试


编译程序,通过ST-Link下载到MCU,搭建好电路,在线监测实时采集到的模拟量数据,模拟量数据源为两路电压模拟量。


网络异常,图片无法展示
|

相关文章
|
传感器 存储 运维
智能物联网:LoRaWAN技术在低功耗广域网中的应用
【10月更文挑战第26天】本文详细介绍了LoRaWAN技术的基本原理、应用场景及实际应用示例。LoRaWAN是一种低功耗、长距离的网络层协议,适用于智能城市、农业、工业监控等领域。文章通过示例代码展示了如何使用LoRaWAN传输温湿度数据,并强调了其在物联网中的重要性和广阔前景。
495 6
|
JSON JavaScript 测试技术
【Docker项目实战】使用Docker部署PPTist在线演示文稿应用
【10月更文挑战第9天】使用Docker部署PPTist在线演示文稿应用
602 2
【Docker项目实战】使用Docker部署PPTist在线演示文稿应用
|
消息中间件
STM32CubeMX FreeRTOS 消息队列
STM32CubeMX FreeRTOS 消息队列
1069 11
R语言错误处理与调试:如何高效调试R代码
【8月更文挑战第28天】调试R代码是一项需要不断练习和提高的技能。通过理解常见的错误类型、使用`traceback()`查看错误路径、逐步执行代码、利用`tryCatch()`捕获和处理错误、设置更严格的警告级别、利用RStudio的调试工具以及编写可复现的示例,你可以更加高效地调试R代码,并快速解决遇到的问题。
1071 3
|
安全 算法 网络安全
C语言在安全领域的应用
本文探讨了C语言在网络安全中的应用,包括密码学算法实现、网络安全工具开发和安全协议实现。C语言因其高效性、可控性和跨平台性,常用于实现AES、RSA等加密算法,开发网络扫描器和入侵检测系统,以及实现SSL/TLS、IPSec等安全协议。代码示例展示了C语言如何进行AES加密解密。尽管C语言在安全领域有显著优势,但面对不断演变的威胁,持续学习和研究新的安全技术至关重要。
|
Arthas Oracle Java
可观测可回溯 | Continuous Profiling 实践解析
我们定位异常时,时常无法知晓代码内部发生了什么,因此无从谈起修复和改善代码。​Continuous Profiling帮助开发者全面掌握、回溯生产环节代码执行细节,增强可观测性。​
可观测可回溯 | Continuous Profiling 实践解析
|
数据采集 机器学习/深度学习 人工智能
探索AI在软件测试中的应用与挑战
【2月更文挑战第28天】 随着人工智能(AI)技术的迅猛发展,其在软件测试领域的应用逐渐显现出巨大的潜力和价值。本文将深入探讨AI在软件测试中的具体应用,包括自动化测试、智能化缺陷检测、测试用例生成等方面,并分析其面临的挑战,如数据质量、模型泛化能力、技术融合等。通过对比分析和案例研究,旨在为软件测试领域提供新的视角和解决方案。
515 1
|
Prometheus Kubernetes 监控
Prometheus Operator(上)
Prometheus Operator(上)
550 0
|
程序员 Shell C语言
【C/C++ main函数】深入探索C++中的main函数及其参数
【C/C++ main函数】深入探索C++中的main函数及其参数
1631 0
strtol()函数与strtoul()函数的用法
strtol()函数与strtoul()函数的用法
319 0