数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
查看: 195|回复: 0

[Arduino] 《ESP32S3 Arduino开发指南》第十九章 ADC实验

[复制链接]
发表于 2025-5-21 09:30:22 | 显示全部楼层 |阅读模式
第十九章 ADC实验
本章,我们将学习ESP32-S3的ADC外设,教会大家如何利用ADC去测量可调变阻器的电压值。
本章分为如下几个小节:
19.1 ADC介绍
19.2 硬件设计
19.3 软件设计
19.4 下载验证


19.1 ADC介绍
19.1.1 ADC简介
生活中接触到的大多数信息是醉着时间连续变化的物理量,如声音、温度、压力等。表达这些信息的电信号,称为模拟信号(Analog Signal)。为了方便存储、处理,在计算机系统中,都是数字0和1信号,将模拟信号(连续信号)转换为数字信号(离散信号)的器件就叫模数转换器(Analog-to-Digital Convert,ADC)。
ADC转换器可分为:并行比较型A/D转换器(FLASH ADC)、逐次比较型A/D转换器(SAR ADC)和双积分式A/D转换器(Double Integral ADC)。
A/D转换过程通常为4步:采样、保持、量化和编码,如下图所示。
图19.1.1.1 A/D转换过程图
采样:把时间连续变化的信号变换为时间离散的信号。
保持:保持采样信号,使有充分时间转换为数字信号。
量化:把采样保持电路的输出信号用单位量化电压的整数倍表示。
编码:把量化的结果用二进制代码表示。
采样和保持通常是在采样-保持电路中完成,量化和编码通常在ADC数字编码电路中完成。
19.1.2 ESP32-S3 ADC介绍
ESP32-S3集成了两个12位SAR ADC,ADC1和ADC2,支持20个模拟通道输入。这20个模拟通道输入对应着具体的IO,并不是随意的IO都有模拟输入功能,具备模拟输入功能的引脚如下表所示。
表19.1.2.1 具备模拟输入功能的引脚
ESP32-S3的ADC模块的分辨率为12位,所以AD转换后的值范围为0~4095。由于ESP32-S3的工作电压为3.3V,所以当AD值为4095时,对应的电压为3.3V;当AD值为0时,对应的电压为0V。对于AD值和电压值,这里就会有一个简单的关系,如下所示。
19.1.3 ADC函数介绍
本小节介绍到的函数可在以下文件中找到:
Arduino15\packages\esp32\hardware\esp32\2.0.11\cores\esp32\esp32-hal-adc.c
接下来,我们介绍一下本章节唯一用到的analogRead函数。
analogRead函数,该函数功能是从指定引脚读取模拟信号,获取返回值。
uint16_t analogRead(uin8_t pin);
参数pin为模拟输入引脚,可以查看一下表19.1.2.1确认该引脚是否有模拟输入功能;
返回值:ADC精度是12bit,默认范围为0~4095之间。
19.2 硬件设计
1. 例程功能
使用ADC采集通道7(IO8)上面的电压,在LCD上面显示ADC转换值以及换算成电压后的电压值。使用短路帽将P3端子中的AIN和RV1排针连接,使得IO8连接到电位器上,然后将ADC采集到的数据和转换后的电压值在LCD屏中显示。用户可以通过调节电位器的旋钮改变电压值。
2. 硬件资源
1)USART0
U0TXD-IO43
U0RXD-IO44
2)XL9555
IIC_SDA-IO41
IIC_SCL-IO42
3)SPILCD
CS-IO21
SCK-IO12
SDA-IO11
DC-IO40(在P5端口,使用跳线帽将IO_SET和LCD_DC相连)
PWR-IO1_3(XL9555)
RST-IO1_2(XL9555)
4)ADC
RV-AIN(IO8)(在P3端口,使用跳线帽将RV和AIN相连)
3. 原理图
ADC相关原理图,如下图所示。
图19.2.1 ADC原理图
本实验,我们通过ADC1的通道7(IO8)来采集外部电压值,开发板有一个电位器,可调节的电压范围是:0~3.3V。我们可以通过跳线帽将IO8与电位器连接,如下图所示:
图19.2.2 IO8(对应AIN排针)与电位器示意图
使用跳线帽将AIN和RV排针连接好后,并下载程序后,就可以用螺丝刀调节电位器变换多种电压值进行测量。
有的朋友可能还想测量其它地方的电压值,我们只需要1根杜邦线,一端接到AIN排针上,另外一端就接你要测试的电压点。一定要保证测试点的电压在0~3.3V的电压范围,否则可能烧坏我们的ADC,甚至是整个主控芯片。
19.3 软件设计
19.3.1 程序流程图
下面看看本实验的程序流程图:
图19.3.1 程序流程图

19.3.2 程序解析
1. ADC驱动代码
这里我们只讲解核心代码,详细的源码请大家参考光盘本实验对应源码。ADC驱动源码包括两个文件:adc.cpp和adc.h。
下面我们先解析adc.h的程序。对模拟输入引脚做了相关定义。
/* 引脚定义 */
#define ADC_IN_PIN      8        
我们选择使用IO8作为读取模拟信号引脚,使用到的是ADC1通道7。
下面,我们继续获取ADC值的函数adc_get,代码如下:
/**
* @brief   获取ADC值函数
* @param    adc_pin:adc引脚
* @retval   获取到的ADC值
*/
uint16_t adc_get(uint8_t adc_pin)
{
    return analogRead(adc_pin);   /* 返回ADC值 */
}
在程序中,我们并不需要对ADC进行配置,就可以直接调用analogRead函数进行读取了。由于ADC的分辨率是12位,所以最终读取的值的范围在0 ~ 4095之间。
2. 13_adc.ino代码
在13_adc.ino里面编写如下代码:
#include "uart.h"
#include "xl9555.h"
#include "spilcd.h"
#include "adc.h"
uint16_t adc_value = 0;
float adc_vol = 0;
/**
* @brief   当程序开始执行时,将调用setup()函数,通常用来初始化变量、函数等
* @param   无
* @retval  无
*/
void setup()
{
    uart_init(0, 115200); /* 串口0初始化 */
    xl9555_init();           /* IO扩展芯片初始化 */
    lcd_init();              /* LCD初始化 */
    lcd_show_string(30, 50, 200, 16, LCD_FONT_16, "ESP32-S3", RED);
    lcd_show_string(30, 70, 200, 16, LCD_FONT_16, "ADC TEST", RED);
    lcd_show_string(30, 90, 200, 16, LCD_FONT_16, "ATOM@ALIENTEK", RED);
    lcd_show_string(30, 110, 200, 16, LCD_FONT_16, "ADC_VAL:", BLUE);
lcd_show_string(30, 130, 200, 16, LCD_FONT_16, "ADC_VOL:0.000V", BLUE);   
}
/**
* @brief   循环函数,通常放程序的主体或者需要不断刷新的语句
* @param  无
* @retval  无
*/
void loop()
{
    adc_value = adc_get(ADC_IN_PIN);          /* 读取GPIO8引脚的ADC值 */
lcd_show_xnum(94, 110, adc_value, 5, LCD_FONT_16, NUM_SHOW_NOZERO, BLUE);
/* 显示ADC采样后的原始值 */
    adc_vol = (float)adc_value * 3.3 / 4095;  /* 换算得到电压值 */
adc_value = adc_vol;  /* 赋值整数部分给adc_value变量,因为adc_value为u16整形 */
   lcd_show_xnum(94,130,(uint16_t)adc_value,1,LCD_FONT_16,NUM_SHOW_NOZERO,BLUE);
    /* 显示电压值的整数部分,3.1111的话,这里就是显示3 */
    adc_vol -= adc_value; /* 把已显示整数部分去掉,留下小数部分,如3.1111-3=0.1111 */
    adc_vol *= 1000;   /* 小数部分乘1000,0.1111转换为111.1,相当于保留三位小数 */
    lcd_fill(110, 130, 110 + 24, 130 + 16, WHITE);
lcd_show_xnum(110, 130, adc_vol, 3, LCD_FONT_16, NUM_SHOW_ZERO, BLUE);
/* 显示小数部分(前面转换为了整形显示),这里显示的就是111 */
    delay(500);
}
在setup函数中,调用uart_init函数完成串口初始化,调用xl9555_init函数完成XL9555初始化,然后调用lcd_init函数完成LCD屏初始化,后面就是LCD显示实验信息。
在loop函数中,调用adc_get函数获取IO8的AD值,然后换算出电压值,通过LCD进行显示。
19.4 下载验证
下载代码后,可以看到LCD显示如下图所示。
图19.4.1 ADC实验测试图

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
您需要登录后才可以回帖 登录 | 立即注册 微信登录

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-7-23 11:04 , Processed in 0.109200 second(s), 11 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

快速回复 返回顶部 返回列表