细说MCU的ADC模块单通道单次采样的实现方法

目录

一、工程依赖的硬件

二、设计目的

三、建立工程

1、配置GPIO

2、配置中断

3、配置串口

4、配置ADC

5、选择时钟源和Debug

6、配置系统时钟和ADC时钟

四、设置采样频率 

五、代码修改 

1、重定义外部中断回调函数

2、启动ADC

3、配置printf函数 

六、运行并查看结果 


        STM32G4系列MCU的模/数转换器(Analog to Digital Converter,ADC)功能比较强不同的型号所含ADC模块数量不同,最多有5个ADC(ADC1~5);但也并非完全独立,其ADC1和ADC2是一对,ADC3和ADC4是一对,ADC5可独立控制。每个ADC都包含一个12位逐次比较型模/数转换器。此外,每个ADC还有最多至19个通道,不同的通道具有单次、连续和扫描或断续等采样模式。

一、工程依赖的硬件

        文章依赖的硬件及工程配置参考本文作者的其他文章:细说ARM MCU的串口接收数据的实现过程-CSDN博客 https://wenchm.blog.csdn.net/article/details/139541112

二、设计目的

        在本例子中,使用ADC1的一个通道以单次采样的模式采集外部输入直流电压信号。使用NUCLEO-G474RE开发板上的按键B1来启动ADC采样。每按下一次B1键,进行一次A/D转换。在代码实现中,将通过查询方式判断是否转换完成;一旦转换成,主程序会从ADC的数据寄存器中读取转换结果,并将结果通过串口送出。此外,当输入信号的幅值大于一定值时,将会点亮板上发光二极管LD2。这个例子用到了ADC、串口入/输出等多个模块。此外,A/D转换虽采用查询模式,但对按键状态的识别,将采用中断方式。

        ADC的输入电压范围是0~3.3 V,所以要确保外部施加的信号不超过此电压范围,否则会导致硬件损坏。

        本例中,采用ADC1的第一个通道,对应STM32G474RE的引脚为PA0,在NUCLEG474RE板上通过CN7端子的第28引脚引出。此外,按键B1连接的引脚为PC13,LD2的控制引脚为PA5。

三、建立工程

1、配置GPIO

        配置PA5为输出(GPIO_Output),默认输出电平Low,推挽输出,上拉,速度High,标识为LED;PA5引脚输出高电平时LD2点亮,默认的低电平时熄灭;

        配置PC13为中断模式(GPIO_EXTI13),上升沿触发,下拉,用户标识为KEY。

2、配置中断

        在NVIC中断表中,将EXTI line[15:10]interrupts使能,并将其抢占式优先级设为2(由于仅用到一个中断,级数选择可任意)。

3、配置串口

        选择 Connectivity中的 USART2,其模式( Mode)选择异步( Asynchronous),其他参数设置均保持默认(波特率为115200 bit/ s),不开启中断。将 USART2的两个引脚 PA2和 PA3均设置为上拉。

4、配置ADC

        选择Analog中的ADC1,在其模式(Mode)区,通道1(IN1)选择IN1 Single-ended(单端);其它参数设置可暂时均保持默认值。时钟预分频参数(Clock Prescaler)选择Asynchronous clock mode dividedby 1(其他选项亦可)。

5、选择时钟源和Debug

        使用片外时钟晶体作为HSE的时钟源。在SYS中将Debug设置为Serial Wire。

6、配置系统时钟和ADC时钟

        在STM32G474RE的说明文档中,给出了其ADC时钟频率的范围。

        ADC的最大频率为60 MHz,而系统最高频率为170 MHz,如果系统频率配置较高,生成ADC时钟频率时就需要分频处理。

        在本例中,没有使用低功耗模式,并且是让ADC进行单次采样的,所以最高时钟频以达到60 MHz。为了可靠起见,本例中配置ADC的时钟频率为34 MHz。

符  号

参  数

条  件

最小值

最大值

fADC/MHz

ADC
时钟频率

Rangel单路ADC操作

0.14

60

Range2

——

26

Range1所有ADCs操作,单端模式VDDA≥2.7 V

0.14

52

Range1所有ADCs操作,单端模式VDDA≥1.62 V

0.14

42

Rangel单路ADC操作,差分模式VDDA≥1.62 V

0.14

56

四、设置采样频率 

 

五、代码修改 

        打开main.c,修改代码。 

1、重定义外部中断回调函数

        由于希望在产生按键中断时,启动ADC采样,所以,需要重定义外部中断EXTI的回调函数。这个回调函数可以写在main.c文件后面的一个注释对中。这里直接给出它的定义:

/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{HAL_ADC_Start(&hadc1);HAL_ADC_PollForConversion(&hadc1,10);ADC1ConvertedValue = HAL_ADC_GetValue(&hadc1);if(ADC1ConvertedValue > 2048)HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_SET);elseHAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_RESET);printf("ADCResult =%d \r\n",ADC1ConvertedValue);
}int __io_putchar(int ch)
{HAL_UART_Transmit(&huart2,(uint8_t *)&ch,1,0xFFFF);return ch;
}
/* USER CODE END 4 */

2、启动ADC

        在外部中断回调函数中调用了三个ADC相关的库幽数。

        首先是启动ADC,用了库函数HAL_ADC_Start(ADC_HandleTypeDef *hadc)。此函数只有一个参数,就是ADC结构体变量。由于在硬件配置中用了ADC1,所以自动生成的代码中已经给出了它的结构体变量,即hadcl。

        调用的第二个库函数是:

HAL_ADC_PollForConversion(ADC_HandleTypeDef *hadc,uint32_t Timeout);

        这个函数是以查询方式等待A/D转换过程的结束。该函数的第二个参数是Timeout,单位为ms。随后,就可以调用库函数HAL_ADC_GetValue(ADC_HandleTypeDef *hadc)来读取A/D转换的结果了。这里用了一个变量ADC1ConvertedValue来存放A/D转换的结果。需要在main.c中定义该变量,可以将其放到main函数前的注释对中:

/* USER CODE BEGIN PV */
uint16_t ADC1ConvertedValue = 0;
/* USER CODE END PV */

        接下来,在回调函数HAL_GPIO_EXTI_Callback()中根据A/D采样值的大小控制发光二极管的亮灭。

3、配置printf函数 

        在回调函数的最后,使用了 printf函数,将 A/ D转换的结果通过串口送出。

        使用 printf函数从串口送出数据,需要在 main.c中将 stdio.h包含进来;此外,还要给出 putchar函数的定义。

/* USER CODE BEGIN 4 */
int __io_putchar(int ch)
{HAL_UART_Transmit(&huart2,(uint8_t *)&ch,1,0xFFFF);return ch;
}
/* USER CODE END 4 */

六、运行并查看结果 

        编译工程并下载到硬件中,将程序运行起来。 

 

 

        打开串口助手程序,设置好串口端口和波特率等参数,单击“打开串口。

        分别用跳线将PA0连接到GND和VDD(3.3 V)上,并操作NUCLEO-G474RE板上B1键。可以看到,连接到GND时每次送的是0,连接到VDD时会每次送来一个接近4095的数,如图截图。

        STM32G474RE上的ADC是12位的,输入电压3.3 V时,理论上对应最大转换值为4095。在将PA0连接到VDD上时,为什么 ADC的转换结果不是4095呢?这是因为板上的VDD并不是稳定的3.3 V,而是有偏差的。对于12位ADC,如果满量程输入电压为3.3 V,则转换结果的每一位对应的电压为3.3/4096 V,约为0.0008 V,即0.8 mV。从截图中的结果看,偏差了几十mV(不同的板子,偏差可能会有所不同)。

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

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

相关文章

mysql5.7windows安装修改密码

mysql5.7windows安装修改密码 1.首先下载Windows 64位安装包2.安装服务3.my.ini4.初始化4.做成Windows服务5.重置密码 1.首先下载Windows 64位安装包 2.安装服务 双击运行安装服务,一直next; 在Choose Setup Type界面中 选择Custom选项,意思…

头歌资源库(14)残缺棋盘

一、 问题描述 二、算法思想 首先,将2^k 2^k的棋盘划分为四个相等大小的子棋盘,定义为左上、左下、右上和右下四个子棋盘。 然后,根据残缺格的坐标,确定其中一个子棋盘是不完整的,即残缺子棋盘。假设残缺子棋盘是左…

新火种AI|Claude 3.5一夜封王超越GPT-4o!留给OpenAI的时间真的不多了...

AI大模型更新换代的速度,的确快到令人难以想象。 相信很多人现在对“最先进AI大模型”的印象还停留在GPT-4,但事实上,大模型领域的头把交椅早已悄然易主了好几回。就在GPT-4惊艳全球不久之后,其“死对头” Anthropic发布了Claude…

“循环购“:快消品行业的创新商业模式引领者

大家好,我是吴军,来自一家在软件开发与商业模式创新领域享有盛誉的公司。我们专注于为企业提供全方位的商城系统搭建及商业模式定制服务。迄今为止,我们已经成功地为众多企业打造了超过200种独特的商业模式,助力他们实现了显著的商…

【PL理论】(26) 内存管理:C语言实现内存管理的方式 | 栈帧的分配和释放 | C/C++ 手动内存管理

💭 写在前面:在前面的章节中,语言的语义只分配了新的内存位置,我们没有讨论内存位置的释放。在实际的语言中,内存位置在执行过程中会被不断地分配和释放。下面的章节,我们将讨论编程语言的这种内存管理&…

基于IDEA的Maven(依赖介绍和引用)

如何通过一个坐标信息(依赖)去引用 ,某个"jar 包" 会在这篇博客进行学习。 目录 一、学习开始 (0)项目的结构组成和 "pom.xml" 文件内容。 (1)首先需要一个标签&#xf…

方差分析【单/双因素方差分析】

文章目录 方差分析一、单因素方差分析(Analysis of Variance)1.方差分析在做什么?2.方差分析的思路:3.方差分析中的计算:4.构造F统计量: 二、双因素方差分析(Two-way ANOVA)1.双因素方差分析在做什么&#…

时序预测 | Matlab基于Transformer多变量时间序列多步预测

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab基于Transformer多变量时间序列多步预测; 2.多变量时间序列数据集(负荷数据集),采用前96个时刻预测的特征和负荷数据预测未来96个时刻的负荷数据; 3…

53【场景作图】纵深感

1 想清楚什么是前 什么是后 如果背景虚化,就不要处理地很平面,如果很平面,就留一个清晰的边缘 2 重叠 遮挡 被遮挡的物体会更远

微信小程序在独立分包中安装自定义依赖组件,构建自定义 npm 依赖

在微信小程序app.json文件中创建一个独立分包 然后在分包文件夹下 创建一个 package.json文件,在文件中添加你要安装的依赖文件及版本 在终端中开始安装依赖:npm i 依赖安装完成后,会产生一个 node_modules文件 需要项目的根目录下的projec…

动态规划:基本概念

Dynamic Programming 动态规划(Dynamic Programming, DP) 是一种算法设计技巧,通常用来解决具有重叠子问题和最优子结构性质的问题。它通过将问题分解为更小的子问题,逐步解决这些子问题并将结果存储起来,以避免重复计…

外星人Alienware m18R1 原厂Windows11系统

装后恢复到您开箱的体验界面,包括所有原机所有驱动AWCC、Mydell、office、mcafee等所有预装软件。 最适合您电脑的系统,经厂家手调试最佳状态,性能与功耗直接拉满,体验最原汁原味的系统。 原厂系统下载网址:http://w…

“拿来主义”学习边框动画(附源码)

“拿来主义”学习边框动画,附源码,CV可用 扫码关注:小拾岁月,发送 “边框动画”,获取源码。 需求分析 从边框的旋转动画,我们可以看出,可以在按钮元素的下方添加给 360旋转 的元素。同时&…

观察者模式(大话设计模式)C/C++版本

观察者模式 扩展&#xff1a;观察者模式——委托 C 参考&#xff1a;https://www.cnblogs.com/Galesaur-wcy/p/15905936.html #include <iostream> #include <list> #include <memory> #include <string> using namespace std;// Observer类 抽象观…

人工智能导论笔记

有关知识表示和推理的零碎知识点 人工智能导论复习题和概念-CSDN博客 机器学习篇 机器学习分类&#xff08;根据样本数据是否带有标签&#xff09;&#xff1a;监督的机器学习、无监督的机器学习、半监督学习。 监督学习又称为“有教师学习”。在监督学习中&#xff0c;模型…

MySQL 面试突击指南:核心知识点解析2

事务并发可能引发的问题 MySQL 是一个客户端/服务器架构的软件,对于同一个服务器来说,可以有多个客户端与之连接,每个客户端与服务器连接后,可以称为一个会话(Session)。每个客户端都可以在自己的会话中向服务器发出请求语句,一个请求语句可能是某个事务的一部分,也就…

什么是距离选通型水下三维激光扫描仪?(下)

距离选通激光水下成像的发展 距离选通激光成像技术始于上世纪60年代&#xff0c;受制于高性能脉冲激光器和选通成像器件发展的制约&#xff0c;激光距离选通成像技术在随后的二十年发展缓慢&#xff0c;直到20世纪90年代&#xff0c;随着硬件技术的不断成熟&#xff0c;该技术…

Prompt 提示词工程:翻译提示

近期在对计算机学习时&#xff0c;许多内容需要看原始的英文论文&#xff0c;对于我这种学渣来说特别不友好&#xff0c;&#x1f937;&#x1f3fb;‍♀️无奈只能一边看翻译&#xff0c;一边学习。 之前有搜到过专门的翻译工具&#xff0c;无奈都是按照字数算费用的&#xf…

【FreeRTOS】删除任务 用遥控器控制音乐

参考《FreeRTOS入门与工程实践(基于DshanMCU-103).pdf》 学习视频&#xff1a;【FreeRTOS入门与工程实践 --由浅入深带你学习FreeRTOS&#xff08;FreeRTOS教程 基于STM32&#xff0c;以实际项目为导向&#xff09;】 【精准空降到 01:22】 https://www.bilibili.com/video/BV1…

模拟原神圣遗物系统-小森设计项目,设计圣遗物词条基类

项目分析 首先需要理解圣遗物的方方面面 比如说圣遗物主词条部分和副词条部分都有那些特点 稍等一会&#xff1a;原神&#xff0c;启动&#xff01; 在此说明了什么&#xff1f; 这是完全体 &#xff1a;主副 词条都有 如果 升级直接暴击率 那么就留点 或者是另外的元素充能 …