细说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);
	else
		HAL_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(不同的板子,偏差可能会有所不同)。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++之模板(二)

1、类模板 2、使用类模板 类模板在使用的时候要显示的调用是哪种类型&#xff0c;而不是像函数模板一样能够根据参数来推导出是哪种类型。 Stack.h #include <stdexcept>template <typename T> class Stack { public:explicit Stack(int maxSize);~Stack();void …

基于Java实训中心管理系统设计和实现(源码+LW+调试文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末获取源码数据库&#x1f31f; 感兴趣的可以先收藏起来&#xff0c;…

ciscn_2019_n_1

前戏--------checksec,运行查看 进入就可以发现这段代码 很浅显易懂 我们要得到的后面是 这里 我们要利用的漏洞是 get函数 0x30大小 加上8 exp: from pwn import * ghust remote("node5.buuoj.cn",28777) addr 0x4006BE payload bA * 0x30 bB*0x8 p64(addr…

Honeyview图片查看:从未如此流畅

名人说&#xff1a;一点浩然气&#xff0c;千里快哉风。 ——苏轼 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、软件介绍1、Honeyview2、核心特点 二、下载安装1、下载2、安装 三、使用方法1、图片打开2、自…

【字符串 状态机动态规划】1320. 二指输入的的最小距离

本文涉及知识点 动态规划汇总 字符串 状态机动态规划 LeetCode1320. 二指输入的的最小距离 二指输入法定制键盘在 X-Y 平面上的布局如上图所示&#xff0c;其中每个大写英文字母都位于某个坐标处。 例如字母 A 位于坐标 (0,0)&#xff0c;字母 B 位于坐标 (0,1)&#xff0…

Flask之模板

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 目录 一、模板的基本用法 1.1、创建模板 1.2、模板语法 1.3、渲染模板 二、模板辅助工具 2.1、上下文 2.2、全局对象 2.3、过滤器 2.4、测试…

投票多功能小程序(ThinkPHP+Uniapp+FastAdmin)

&#x1f389;你的决策小助手&#xff01; 支持图文投票、自定义选手报名内容、自定义主题色、礼物功能(高级授权)、弹幕功能(高级授权)、会员发布、支持数据库私有化部署&#xff0c;Uniapp提供全部无加密源码。​ 一、引言&#xff1a;为什么我们需要多功能投票小程序&#…

AI+前端技术的结合(实现图片识别功能)

随着人工智能技术的不断发展&#xff0c;AI在前端设计页面中的应用变得越来越普遍。比如&#xff1a;在电商平台上&#xff0c;可以利用对象检测技术实现商品的自动识别和分类&#xff1b;人脸识别&#xff1b;车辆检测&#xff1b;图片识别等等......其中一个显著的应用是在图…

ArcGIS与Excel分区汇总统计三调各地类面积!数据透视表与汇总统计!

​ 点击下方全系列课程学习 点击学习—>ArcGIS全系列实战视频教程——9个单一课程组合系列直播回放 点击学习——>遥感影像综合处理4大遥感软件ArcGISENVIErdaseCognition 01 需求说明 介绍一下ArcGIS与Excel统计分区各地类的三调地类面积。 ArcGIS统计分析不会&#x…

SpringBoot测试实践

测试按照粒度可分为3层&#xff1a; 单元测试&#xff1a;单元测试&#xff08;Unit Testing&#xff09;又称为模块测试 &#xff0c;是针对程序模块&#xff08;软件设计的最小单位&#xff09;来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。在过程化编程中…

Linux驱动开发笔记(十三)Sysfs文件系统

文章目录 前言一、Sysfs1.1 Sysfs的引入1.2 Sysfs的目录结构1.2 Sysfs的目录详解1.2.1 devices1.2.2 bus1.2.3 class1.2.4 devices、bus、class目录之间的关系1.2.5 其他子目录 二、Sysfs使用2.1 核心数据结构2.2 相关函数2.2.1 kobject_create_and_add2.2.2 kobject_put()2.2.…

视觉理解与图片问答,学习如何使用 GPT-4o (GPT-4 Omni) 来理解图像

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一、引言 OpenAI 最新发布的 GPT-4 Omni 模型&#xff0c;也被称为 GPT-4o&#xff0c;是一个多模态 AI 模型&#xff0c;旨在提供更加自然和全面的人机交互体验。 GPT-4o 与 GPT-4 Turbo 都具备视觉功…

MySQL程序使用的选项文件

MySQL程序使用的选项文件如下&#xff1a; 显示帮助消息并退出。 在具有多个网络接口的计算机上&#xff0c;使用此选项可以选择用于连接MySQL服务器的接口。 安装字符集的目录。 如果可能&#xff0c;压缩客户端和服务器之间发送的所有信息。 从MySQL 8.0.18开始&#xff0c;…

【因果推断python】50_去偏/正交机器学习2

目录 Frisch-Waugh-Lovell on Steroids CATE Estimation with Double-ML Frisch-Waugh-Lovell on Steroids 双重/偏差 ML 其思想非常简单&#xff1a;在构建结果和治疗残差时使用 ML 模型&#xff1a; 是估计&#xff0c;是估计 我们的想法是&#xff0c;ML 模型具有超强的…

【RK3588/算能/Nvidia智能盒子】AI算法应用于中国生物疫苗生产过程智能监测,赋能生产安全,提升品质管控

因操作失误导致食品药品质量事故频发 计算机视觉检测技术为监管提供新思路 近年来&#xff0c;各类因人员操作失误导致的食品药品质量事故不断发生。例如有员工取出原材料及称重确认时未进行双人复核导致“混药”、员工未能按照生产步骤对生牛奶进行杀菌导致奶酪污染、员工误将…

webpack5入门,根据官方文档简单学习,简单总结

c.**loader加载器&#xff1a;**webpack 只能理解 JS文件和 JSON 文件&#xff0c;loader 让 webpack 能够去处理其他类型的文件&#xff0c;并将它们转换为有效 模块&#xff0c;以供应用程序使用&#xff0c;以及被添加到依赖图中。&#xff08;比如css&#xff0c;less&…

人人讲视频如何下载

一、工具准备 1.VLC media player 2.谷歌浏览器 二、视频下载 1.打开人人讲网页&#xff0c;需要下载的视频 谷歌浏览器打开调试窗口 搜索m3u8链接 拷贝到VLCplayer打开网络串流方式打开测试是否能正常播放 2.下载视频 能正常播放后&#xff0c;切换播放为转换选择mp4格式…

分享excel全套教程速成,高效人士的Excel必修课,附视频课程!

我是阿星。今天&#xff0c;我要来聊聊那些让Excel变得像魔法一样的课程&#xff0c;它们能让你们在办公室里像超人一样高效。别急&#xff0c;听我慢慢道来。 首先&#xff0c;得说说这些课程&#xff0c;它们都是mp4格式&#xff0c;就像电影一样&#xff0c;但比电影实用多…

Python一文轻松搞定正则匹配

一、前言 日常工作中&#xff0c;不可避免需要进行文件及内容的查找&#xff0c;替换操作&#xff0c;python的正则匹配无疑是专门针对改场景而出现的&#xff0c;灵活地运用可以极大地提高效率&#xff0c;下图是本文内容概览。 ​ 二、正则表达式符号 对于所有的正则匹配表达…

强化学习中的自我博弈(self-play)

自我博弈&#xff08;Self-Play&#xff09;[1]是应用于智能体于智能体之间处于对抗关系的训练方法&#xff0c;这里的对抗关系指的是一方的奖励上升必然导致另一方的奖励下降。通过轮流训练双方的智能体就能使得双方的策略模型的性能得到显著提升&#xff0c;使得整个对抗系统…