STM32HAL库单ADC+DMA学习及测试记录

news2025/2/25 18:36:48

一、打开STM32CubeMX选择对应的芯片型号,后进入开发界面
1、双击“STM32CubeMX”软件打开,打开后如下图所示,选择红色框;
在这里插入图片描述
选择后可能会更新,等待更新完成即可,如下图:
在这里插入图片描述
2、选择开发芯片,作者本例程的芯片是STM32F407VET6,读者根据自己使用的开发板芯片选择即可。操作如下:
按照下图步骤:
步骤1:输入开发使用的芯片型号,作者这里输入:STM32F407VET6,就会在步骤2显示芯片的具体型号;
步骤2:选择具体使用的芯片型号,选中后会高亮;
步骤3:点击“Start Project”,开始进入工程图形配置界面。

二、图形界面配置
由于采集的ADC数据需要查看,所以本例程采用的是通过串口输出采集的数据,输出到电脑端的串口调试助手。
所以除了基本的时钟、晶振等一些配置,还包含串口配置和ADC配置。
1、配置晶振
步骤1:选择“Pinout&Configuration”;
步骤2:选择“System Core”;
步骤3:选择“RCC”;
步骤4、5:选项下拉选择“Crystal/Ceramic Resonator”
下拉选项说明:
Crystal/Ceramic Resonator:晶体/陶瓷晶振,一般使用的都是这个
BYPASS Clock Source:旁路时钟源
在这里插入图片描述
2、配置DEBUG和SYS
步骤1:选择“Pinout&Configuration”;
步骤2:选择“System Core”;
步骤3:选择“SYS”;
步骤4:选择“Serial Wire”;
此选项是下载调试的方式选择,有很多种,包括SWD、JTAG等方式,我是ST-link/V2 下载器来下载
步骤5:选择“Sys Tick”;
此选项是HAL时基的选择,有滴答定时器,和其它定时器1、2、3、4、5…,这里选择SysTick滴答定时器。

在这里插入图片描述
3、配置调试输出串口1
步骤1:选择“Pinout&Configuration”;
步骤2:选择“Connectivity”;
步骤3:选择“USART1”;
步骤4:选择“Asynchronous”;
此下拉选项有多种选择,分别如下:
Asynchronous:异步通信
Synchronous:同步通信
Single Wire(Half-Duplex):半双工
Multiprocessor Communication:多处理器通信
lrDA:红外数据
LIN:局域网互联
SmartCard:智能卡
步骤5:选择“NVIC Settings”->然后勾选中断使能。
选项卡“Parameter Settings”是设置串口的参数
Basic Parameters->Baud Rate:设置波特率,默认115200,可不修改;
Basic Parameters->Word Length:字长,默认“8Bits”,默认即可;
Basic Parameters->Parity:奇偶校验,默认选择"None"无校验;默认即可;
Basic Parameters->Stop Bits:停止位,默认1,默认即可;
Advanced Parameters->Data Direction:数据方向,默认“Receive and Transmit”可接收发送,默认即可;
Advanced Parameters->Over Sampling:过采样长度,默认“16 Samples”16个采样,默认即可;
选项卡“NVIC Settings”是设置中断使能-勾选对应的中断信号源即可,本工程只勾选“USART1 global interrupt”;
选项卡“DMA Settings”是设置串口DMA通道的,可添加DMA,在本工程,不使用。
其它选项卡无需设置。
在这里插入图片描述
4、配置ADC,使用ADC1通道1,即PA1引脚
步骤1:选择“Pinout&Configuration”;
步骤2:选择“Analog”;
步骤3:选择“ADC1”;
步骤4:选择“IN11和IN12以及IN13”,表示选择通道11、通道12、通道13, 此选项是选项ADC的通道,
步骤5:ADC参数配置
步骤6:勾选ADC通道后在右侧标记变绿可看到对应的IO选中。

重点讲解ADC参数
选项卡“Parameter Settings”是设置ADC的参数,如图所示;
(1)ADCs_Common_Settings->Mode:ADC的模式,默认选择“Independent mode”,独立模式,默认即可;
(2)ADC_Settings->Clock Prescaler:时钟预分频,默认选择“PCLK2 divided by 4”,2分频,ADC分频后的时钟最好不要高于36MHz;ADC在APB2时钟线上,后面配置时钟树时,会得到APB2是84MHz,所以本工程此选项选择“PCLK2 divided by 4”,4分频
(3)ADC_Settings->Resolution:ADC 分辨率,默认“12Bits",默认即可;
(4)ADC_Settings->Data Alignment:数据对齐对齐方式,默认“Right alignment”,右对齐,默认即可;
(5)ADC_Settings->Scan Conversion Mode:扫描,默认“Disable”,不使能,如果多通道可使能,此处需要使能“Enabled”;
(6)ADC_Settings->Continuous Conversion Mode:连续转换,默认“Disable”,不使能,如果多通道或连续采集信号时可使能,此处需要使能“Enabled”;
(7)ADC_Settings->Discontinuous Conversion Mode:不连续转换,默认“Disable”,不使能;
(8)ADC_Settings->DMA Continuous Requests:DMA 连续请求,默认“Disable”,不使能,使用DMA时可使能,此处需要使能“Enabled”;
(9)ADC_Settings->End Of Conversion Selection:转换结束选择,默认“EOC flag at the end of single channel conversion”,单通道转换结束时的 EOC 标志,默认即可;
(10)ADC_Regular_ConversionMode->Number Of Conversion:转换次数,由于我们选择了三个 ADC通道,所以此处需要填写3;
(11)ADC_Regular_ConversionMode->External Trigger Conversion Source,外部触发转换源,默认“Regular Conversion launched by software”由软件启动的定期转换,默认即可;
(12)ADC_Regular_ConversionMode->External Trigger Conversion Edge,外部触发转换边沿,默认“None”,默认即可;
(13)ADC_Regular_ConversionMode->Rank->Channel,选择ADC的通道,在前面则通道后,处选择对应的Channel即可,如果只用到3个通道,会衍生出三个Rank选项。分别要填写我们需要采集的ADC通道,这里分别填写11 、12 、13;
(14)ADC_Regular_ConversionMode->Rank->Sampling Time,采样时间,小一些比较快,但是可能采集的信号波动大,大一些时间长一点,采集的波动小;
(15)ADC_Injected_ConversionMode->Number Of ConversionMode(注入通道转换模式),转换模式数,默认即可。
注入通道数不为0时,才有下面的配置项
<1> Number of Conversion ADC转换的注入通道数
<2> External Trigger Source ADC外部触发转换源
<3> External Trigger Edge ADC外部触发转换边沿(意思是上升沿/下降沿触发)
<4> Injected Conversion Mode ADC注入转换通道模式

(16)WatchDog->Enable Analog WatchDog Mode,看门口,默认不勾选,默认即可;

在这里插入图片描述

5,NVIC配置
步骤1:选择“ADC2”;
步骤2:选择“NVIC Setting”;
步骤3:勾选“ADC1, ADC2 and ADC3 global interrupts”的使能;启用优先级通道
在这里插入图片描述

6,进行DMA配置
步骤1:选择“ADC2”;
步骤2:选择“DMA Setting”;
步骤3:前面ADC设置中有启用了DMA通道,使用这里显示了ADC2的DMA信息 保持默认即可或根据需要修改对应的信息
Stream DMA 通道流,Direction 传输方向 由于这里是外设到内存,priority 优先级 ;
步骤2:选择“DMA Setting”;

使能DMA连续请求,就应该采用循环模式Circular Mode,它意味着可以重复加载数据到目标地址
在这里插入图片描述

三、配置系统时钟
步骤1:选择“Clock&Configuration”;
步骤2:外部高速晶振的大小,作者用的开发板上,外部高速晶振大小时8MHz,读者根据自己使用的开发板上的晶振大小输入对应的值即可;
步骤3:选择器选择下面园点,即选中外部晶振作为输入源;如果电路没外部晶振,可选择上面圆点,选择芯片内部高速晶振作为输入,本工程选外部输入;
步骤4:选择“PLLCLK”,就是选择倍频器PLL作为输入时钟源,如果没外部高速晶振,则选择HSI(第一个圆点);
步骤5:直接输入“168”,作为系统的主频大小。
以上修改完成后 回车,如果右提示,选择确认即可。

在这里插入图片描述
参考下图选择,高亮的位置都可以修改,修改后的值如下图所示:

四、工程输出配置
1、项目文件配置
步骤1:选择“Project Manager”
步骤2:选择“Project”
步骤3:输入工程名称,作者这里输入“ADC”,表示ADC功能的工程,一般名称体现工程的作用,可以自定义;
步骤4:点击“Browse”,选择工程存放的路径,不要包含中文;
步骤5:下拉选择“MDK-ARM”,表示用的IDE是keil;可以根据自己使用的编程软件选择,这里作者选用“MDK-ARM”;后面的“V5.27”则是软件的版本号;
步骤6:芯片的HAL库固件包,勾选后面,会自动选择,一般会自动更新到最新版本;
在这里插入图片描述

2、代码生成配置
步骤7:选择“Code Generator”;
步骤8:STM32Cube MCU packages and embedded software packs,STM32Cube MCU 软件包和嵌入式软件包选择,本工程选中第一条;
第一条:Copy all used libraries into the project folder:将所有使用的库复制到项目文件夹中;
第二条:Copy only the necessary library files:只复制必要的库文件;
第三条:Add necessary library files as reference in the toolchain project configuration file:在工具链项目配置文件中添加必要的库文件作为参考;
建议选中第一条,将所以的包含,避免后续开发出现遗漏的文件,方便后续功能增加,就是工程代码量会大一些;

步骤9:Generated files,生成文件,本工程选中,第一、三、四,三个选项;
第一条:Generate pripheral initalization as a pair of ‘.c/.h’ files per peripheral:将外围设备初始化生成为每个外围设备的一对“.c/.h”文件
第二条:Backup previously generated files when re-generating,重新生成时备份以前生成的文件
第三条:Keep User Code when re-generating,重新生成时保留用户代码
第四条:Delete previously generated files when not re-generated ,不重新生成时删除以前生成的文件
步骤10:点击“GENERATE CODE”
在这里插入图片描述

点击生成后弹出提示框,点击“Open Project”,即可打开工程。
在这里插入图片描述
五、代码补充
1、补充串口代码
串口是为了方便测试查看ADC的采集数据,重定向了printf函数,具体操作如下:
打开“usart.c”文件,
在文件头文件引用的“/* USER CODE BEGIN 0 /” 和“ / USER CODE END 1 */ ”之间添加如下代码:

#include "stdio.h"

在末尾的“/* USER CODE BEGIN 1 /” 和“ / USER CODE END 1 */ ”之间添加如下代码:

#if 1
//#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE 
{ 
	int handle; 
}; 
 
FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x) 
{ 
	x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{ 	
	 HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0x0001);  
	return ch;
}

在Whil循环中添加

  while (1)
  {
    /* USER CODE END WHILE */

//		i=0;
//		printf("\r\n");
//			ad1 += ADC_Value[i++];
//			printf("ADC1_value=%d\r\n", ADC_Value[i]);
//			ad2 += ADC_Value[i++];
						printf("ADC2_value=%d\r\n", ADC_Value[i]);
//			ad3 += ADC_Value[i++];
//			printf("ADC3_value=%d\r\n", ADC_Value[i]);

		
		
//		printf("\r\n");
				for(i = 0 , ad1 =0 , ad2=0 , ad3=0; i < 19; )
		{	
			
			ad1 += ADC_Value[i++];
//						printf("%d\r\n", ADC_Value[i]);
			ad2 += ADC_Value[i++];
//						printf("ADC2_value=%d,位置:%d\r\n", ADC_Value[i]);
			ad3 += ADC_Value[i++];
//						printf("ADC3_value=%d\r\n", ADC_Value[i]);
			printf("%d\r\n", ADC_Value[i]);
		}
//		ad1 /= 10;
//		ad2 /= 10;//均值输出
//		ad3 /= 10;//均值输出
		
//		printf("\r\n");
//		printf("ADC1_value=%.3fV\r\n", ad1*3.3f/4096);
		printf("ADC2_value=%.3fV\r\n" ,ad2*3.3f/4096);//打印
//		printf("ADC3_value=%.3fV\r\n" ,ad3*3.3f/4096);//打印
		HAL_Delay(500) ;
		
		
    /* USER CODE BEGIN 3 */
  }

通过连接0V或3.3V电压,再printf打印输出可确定引脚对应的通道,也可区分 DMA搬运时对应的数据。
最近我发现循环中超出一定的数量 打印多个数据后。精准ADC准确度下降,准确来说是数据位好像偏移了。后面没有深究

七、总结
1.本次的ADC转化时间计算为
配置为:
外挂8M晶振
系统时钟 168M
ADC挂在PCLK2时钟下,ADC分频:4 ,ADC时钟:21M
采样间隔:3 cycles
TCONV(转换时间) = 采样时间+ 12.5 个周期
3 + 12.5 = 15.5
采样通道数:3
采样时间 =(3+12.5)*3 / 21M = 2.214us

其他ADC采样时间、采样周期、采样频率计算方法链接如下:

https://www.cnblogs.com/lifan3a/articles/10968911.html

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

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

相关文章

【剧前爆米花--爪哇岛寻宝】面向对象的三大特性——封装、继承以及多态的详细剖析(上——继承)。

作者&#xff1a;困了电视剧 专栏&#xff1a;《JavaSE语法与底层详解》 文章分布&#xff1a;这是一篇关于Java面向对象三大特性——继承的文章&#xff0c;在本篇文章中我会分享继承的一些基础语法以及类在继承时代码的底层逻辑和执行顺序。 目录 继承 需求 继承的定义及语…

nginx(六十八)proxy模块(八)nginx与上游的ssl握手

一 nginx作为客户端与上游的SSL/TLS握手 理解上&#xff1a; nginx作为客户端,此时类似浏览器的角色,发请求建立连接 nginx作为server端与下游进行SSL/TLS握手 ① nginx与后端选择什么样的协议 1&#xff09;如果nginx与上游是局域网内,一般通过http建立请求,不需要进行…

详解__int128,最大可用整数类型

前言&#xff1a;有些题目需要的数值刚好比 long long 的最大值大那么一点点&#xff0c;那么我们就可以用__int128 来搏一搏&#xff08;并不是所有OJ都支持这个数据类型&#xff0c;受编译标准影响&#xff09; 最大值是多少 int 最大值&#xff1a;2^(32-1)-1【受电脑字长影…

碳中和专题:碳足迹核算、碳中和顶刊论文、碳排放交易2022

&#xff08;1&#xff09;碳中和顶刊论文 1、数据来源&#xff1a;自身 2、具体内容&#xff1a; 01周宏春&#xff1a;碳循环经济内涵、实践及其碳中和的深远影响.pdf 02谢和平&#xff1a;碳中和目标下煤炭行业发展机遇.pdf 03秦阿宁&#xff1a;碳中和背景下的国际绿色技…

【FPGA】基于状态机实现自动售货机模拟

文章目录一、售货机功能二、售货机状态分析及模块划分三、代码实现四、上板验证一、售货机功能 此自动售货机模拟基于EP4CE6F17C8开发板实现&#xff0c;用按键&#xff0c;led灯&#xff0c;数码管表示各个输入输出 功能&#xff1a; 此自动售货机可以选择A&#xff08;三元…

[激光原理与应用-21]:《激光原理与技术》-7- 激光技术大汇总与总体概述

目录 前言&#xff1a; 第1章 什么是激光技术 1.1 什么是激光技术 1.2 激光技术的分类方法 第2章 激光的应用技术 2.1 激光加工技术 2.2 激光快速成型 2.3 激光切割 2.4 激光焊接 2.5 激光雕刻 2.6 激光打孔 2.7 激光蚀刻 2.8 激光手术 2.9 激光武器 2.10 激光能…

详解诊断数据库ODX-D

文章目录 前言一、ODX-D具体内容是什么?二、ODX企标中关于ODX-D定义内容三、ODX-D在CANdelaStudio以及ODXStudio中定义内容总结前言 ​又是一周末,静下心码下字,将ODX这个Topic补充完整。 ODX含义是开放式诊断数据交互,是欧洲那边提出诊断数据架构,详情可如下图: 核心…

区间信息维护与查询【树状数组 】 - 原理2 多维树状数组

区间信息维护与查询【树状数组 】 - 原理2 多维树状数组 我们已经知道一维树状数组修改和查询的时间复杂度均为O (logn)&#xff0c;可以扩展为m 维树状数组&#xff0c;其时间复杂度为O (log ^m n )&#xff0c;对该算法只需加上一层循环即可。二维数组a [n ][n ]、树状数组c…

创建TCP通信与粘包问题解决

创建TCP通信 nodeJS的Net模块实现了底层通信接口 通信过程 创建服务端&#xff1a;接收和回写客户端数据创建客户端&#xff1a;发送和接收服务端数据数据传输&#xff1a; 内置服务事件和方法读写数据 通信事件 listing事件&#xff1a;调用server.listen方法之后触发con…

介绍 10 个有用的 Flutter 软件包

介绍 10 个有用的 Flutter 软件包 原文 https://genotechies.medium.com/introducing-10-useful-flutter-packages-1252c4b75fa7 前言 FLutter 软件包使您的开发简单快速。然而&#xff0c;有利有弊。有时候&#xff0c;如果从头开始开发这个特性将是有益的&#xff0c;因为可定…

Hive日分区表如何快速导入到StarRocks

1、背景 业务现状&#xff1a;集团使用FineBI做数据呈现及报表分析工具&#xff0c;经过近两年的BI建设&#xff0c;供应链域及营销域的BI建设已初具规模并体系化。数仓规模60TB&#xff0c;FineBI数据集约8000个&#xff0c;BI挂出报表数约1600个&#xff0c;报表月增幅在40左…

非凡社群管理之社群管理有什么内容

社群作为一个非常重要的私域流量池&#xff0c;它本身就是一个提升用户价值的利器。但如果管理不好社群&#xff0c;那么也是无济于事的。 社群小助手提示&#xff1a;高效管理社群&#xff0c;以下这五个方面要做好。 一&#xff0c;社群为用户解决问题&#xff0c;让群成员都…

iwebsec靶场 SQL注入漏洞通关笔记6- 宽字节注入

系列文章目录 iwebsec靶场 SQL注入漏洞通关笔记1- 数字型注入_mooyuan的博客-CSDN博客 iwebsec靶场 SQL注入漏洞通关笔记2- 字符型注入&#xff08;宽字节注入&#xff09;_mooyuan的博客-CSDN博客 iwebsec靶场 SQL注入漏洞通关笔记3- bool注入&#xff08;布尔型盲注&#…

【ML特征工程】第 7 章 :通过K-Means 模型堆叠进行非线性特征化

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

计算机视觉之目标检测(object detection)《1》

在计算机视觉领域&#xff0c;除了识别图像并分类之外&#xff0c;我们很多时候想关注图像里面一些感兴趣的目标&#xff0c;比如视频监控中寻找一个或多个嫌疑犯&#xff1b;无人驾驶需要识别车辆、行人、红绿灯、路障等等&#xff0c;都是需要去及时掌握画面中的不同目标。我…

古瑞瓦特能源通过聆讯:上半年营收23亿 IDG投资9亿持股6.5%

雷递网 雷建平 11月26日古瑞瓦特能源&#xff08;简称&#xff1a;“Growatt Technology”&#xff09;日前递交招股书&#xff0c;准备在香港上市。上半年营收23.45亿古瑞瓦特能源于2011年在深圳成立&#xff0c;是一家分布式能源解决方案提供商&#xff0c;专注于可持续能源发…

Crack:GoJS 2.2.18 -2022-09-08 update

使用 JavaScript 和 TypeScript 为 Web 构建图表 流程图 构建交互式流程图或流程图。让您的用户使用 JSON 模型输出构建、修改和保存图表。状态图 可视化状态图和其他行为图。创建具有实时更新的图表以监控状态&#xff0c;或创建交互式图表以进行规划。桑基图 GoJS 允许对链接…

史上最全MATLAB误差分析工具箱,不看别后悔 【矢量化代码、效率嘎嘎快、支持计算50种指标】

在拟合、插值、模拟预测等计算中&#xff0c;往往需要通过不同指标参数来分析实际值与计算值之间差异依次衡量相关方法的可行性。常用的表征指标有残差平方和(SSE)、均方差(MSE)、均方根差(RMSE)、平均绝对误差(MAE)和决定系数R方(R-Squared)等等。 考虑到误差分析在实际应用中…

Kafka部署安装及简单使用

一、环境准备 1、jdk 8 2、zookeeper 3、kafka 说明&#xff1a;在kafka较新版本中已经集成了zookeeper&#xff0c;所以不用单独安装zookeeper&#xff0c;只需要在kafka文件目录中启动zookeeper即可 二、下载地址 Apache Kafka 三、部署 1、启动zookeeper -- 启动 .…

CSDN第11次竞赛题解与总结

CSDN第11次竞赛题解与总结前言建议题解T1圆小艺扩展完整代码T2K皇把妹完整代码T3筛选宝物完整代码T4圆桌完整代码总结前言 2022/11/27 CSDN第11次竞赛 由「壹合原码 & CSDN」联合主办 本次奖励还是不错的 (毕竟有赞助商)&#xff0c;前三十名都有奖励&#xff0c;连以前第…