第二十四章 ADC实验
1)实验平台:正点原子DNESP32S3开发板
2)章节摘自【正点原子】ESP32-S3使用指南—IDF版 V1.6
3)购买链接:https://detail.tmall.com/item.htm?&id=768499342659
4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/esp32/ATK-DNESP32S3.html
5)正点原子官方B站:https://space.bilibili.com/394620890
6)正点原子DNESP32S3开发板技术交流群:132780729
本章介绍使用ESP32-S3模数转换器(ADC)进行带通道的电压采集。通过本章的学习,读者将学习到单通道ADC的使用。
本章分为如下几个小节:
24.1 ADC简介
24.2 硬件设计
24.3 程序设计
24.4 下载验证
24.1 ADC介绍
24.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步:采样、保持、量化和编码,如下图所示。
图24.1.1.1 A/D转换过程图
采样:把时间连续变化的信号变换为时间离散的信号。
保持:保持采样信号,使有充分时间转换为数字信号。
量化:把采样保持电路的输出信号用单位量化电压的整数倍表示。
编码:把量化的结果用二进制代码表示。
采样和保持通常是在采样-保持电路中完成,量化和编码通常在ADC数字编码电路中完成。
24.1.2 ESP32-S3 ADC介绍
ESP32-S3集成了两个12位SAR ADC,ADC1和ADC2,支持20个模拟通道输入。这20个模拟通道输入对应着具体的IO,并不是随意的IO都有模拟输入功能,具备模拟输入功能的引脚如下表所示。
表24.1.2.1 具备模拟输入功能的引脚
ESP32-S3的ADC模块的分辨率为12位,所以AD转换后的值范围为0~4095。由于ESP32-S3的工作电压为3.3V,所以当AD值为4095时,对应的电压为3.3V;当AD值为0时,对应的电压为0V。对于AD值和电压值,这里就会有一个简单的关系,如下所示。
24.2 硬件设计
24.2.1 例程功能
- 本章实验功能简介:使用ADC采集通道7(IO8)上面的电压,在SPILCD模块上面显示ADC转换值以及换算成电压后的电压值。在P3端口中,使用短路帽将AIN和RV1排针连接,使得IO8连接到电位器上,然后将ADC采集到的数据和转换后的电压值在SPILCD屏中显示。用户可以通过调节电位器的旋钮改变电压值。LED闪烁,提示程序运行。
- LED闪烁,指示程序正在运行。
24.2.2 硬件资源
- LED
LED - IO1
- XL9555
IIC_SDA-IO41
IIC_SCL-IO42
- SPILCD
CS-IO21
SCK-IO12
SDA-IO11
DC-IO40(在P5端口,使用跳线帽将IO_SET和LCD_DC相连)
PWR- IO1_3(XL9555)
RST- IO1_2(XL9555)
- ADC
ADC1_CHANNEL_7
24.2.3 原理图
ADC属于ESP32-S3内部资源,实际上我们只需要软件设置就可以正常工作,另外还需要将待测量的电压源连接到ADC通道上,以便ADC测量。本实验,我们通过ADC1的通道7(IO8)来采集外部电压值,开发板有一个电位器,可调节的电压范围是:0~3.3V。我们可以通过跳线帽将IO8与电位器连接,如下图所示:
图24.2.3.1 IO8(对应AIN排针)与电位器引脚示意图
使用杜邦线将ADC和RV1排针连接好后,并下载程序后,就可以用螺丝刀调节电位器变换多种电压值进行测量。
有的朋友可能还想测量其它地方的电压值,我们只需要1根杜邦线,一端接到AIN排针上,另外一端就接你要测试的电压点。一定要保证测试点的电压在0~3.3V的电压范围,否则可能烧坏我们的ADC,甚至是整个主控芯片。
24.3 程序设计
24.3.1 程序流程图
程序流程图能帮助我们更好的理解一个工程的功能和实现的过程,对学习和设计工程有很好的主导作用。下面看看本实验的程序流程图:
图24.3.1.1 ADC实验程序流程图
24.3.2 ADC函数解析
ESP-IDF提供了一套API来配置ADC。要使用此功能,需要导入必要的头文件:- #include " esp_adc_cal.h"#include " driver/adc"
复制代码 接下来,作者将介绍一些常用的ESP32-S3中的ADC函数,这些函数的描述及其作用如下:
1,配置ADC
该函数用于配置ADC各项参数,其函数原型如下所示:- esp_err_t adc_digi_controller_configure(const adc_digi_configuration_t *config);
复制代码 该函数的形参描述,如下表所示:
表24.3.2.1 函数adc_digi_controller_configure()形参描述
返回值:ESP_OK表示配置成功。其他表示配置失败。
该函数使用adc_digi_pattern_config_t以及adc_digi_configuration_t类型的结构体变量传入,该结构体的定义如下所示:
表24.3.2.2 adc_digi_pattern_config_t结构体参数值描述
表24.3.2.3 adc_digi_configuration_t结构体参数值描述
完成上述结构体参数配置之后,可以将结构传递给 adc_digi_controller_configure() 函数,用以实例化ADC。
2,读取ADC原始数据
该函数用于读取ADC原始数据,其函数原型如下所示:- int adc1_get_raw(adc1_channel_tchannel);
复制代码 该函数的形参描述,如下表所示:
表24.3.2.4 函数adc1_get_raw()形参描述
返回值:其他值表示ADC原始数值,-1表示读取失败。
24.3.3 ADC驱动解析
在IDF版14_adc例程中,作者在14_adc \components\BSP路径下新增了一个ADC文件夹,分别用于存放adc.c、adc.h这两个文件。其中,adc.h文件负责声明ADC相关的函数和变量,而adc.c文件则实现了ADC的驱动代码。下面,我们将详细解析这两个文件的实现内容。
1,adc.h文件- /* ADC采集通道定义 */#define ADC_ADCX_CHY ADC1_CHANNEL_7
复制代码 2,adc.c文件- /*** @brief 初始化ADC* @param 无* @retval 无*/void adc_init(void){adc_digi_pattern_config_tadc1_digi_pattern_config; /* ADC1配置句柄 *//* ADC1初始化句柄 */ adc_digi_configuration_t adc1_init_config; /* 配置ADC1 */ adc1_digi_pattern_config.atten = ADC_ATTEN_DB_11; /* 配置ADC衰减程度 */ adc1_digi_pattern_config.channel = ADC_ADCX_CHY; /* 配置ADC通道 */ adc1_digi_pattern_config.unit = ADC_UNIT_1; /* 配置ADC单元 */adc1_digi_pattern_config.bit_width = ADC_BITWIDTH_12; /* 配置ADC位宽 *//* 配置将要使用的每个ADC参数 */ adc1_init_config.adc_pattern = &adc1_digi_pattern_config; adc_digi_controller_configure(&adc1_init_config); /* 配置ADC1 */}
复制代码 从上面的代码中可以看出,ADC的初始化函数中,配置了 ADC1通道7。
ADC驱动中,获取ADC转换结果的函数,如下所示:- /*** @brief 获取ADC转换且进行均值滤波后的结果* @param ch :通道号, 0~9* @param times :获取次数* @retval 通道ch的times次转换结果平均值*/uint32_tadc_get_result_average(uint32_t ch, uint32_t times){ uint32_t temp_val = 0; uint8_t t; for (t = 0; t < times; t++) /* 获取times次数据 */ { temp_val += adc1_get_raw(ch); vTaskDelay(5); } return temp_val / times; /* 返回平均值 */}
复制代码 以上函数用于获取ADC转换结果的函数,函数adc_get_result_averagr()则是多次调用adc1_get_raw()获取多次ADC的转换结果,然后进行均值滤波。
24.3.4 CMakeLists.txt文件
打开本实验BSP下的CMakeLists.txt文件,其内容如下所示:- set(src_dirs ADC IIC LCD LED SPI XL9555)set(include_dirs ADC IIC LCD LED SPI XL9555)set(requires driver esp_adc)idf_component_register(SRC_DIRS ${src_dirs}INCLUDE_DIRS ${include_dirs} REQUIRES ${requires})component_compile_options(-ffast-math -O3 -Wno-error=format=-Wno-format)
复制代码 上述的红色ADC驱动以及esp_adc依赖库需要由开发者自行添加,以确保ADC驱动能够顺利集成到构建系统中。这一步骤是必不可少的,它确保了ADC驱动的正确性和可用性,为后续的开发工作提供了坚实的基础。
24.3.5 实验应用代码
打开main/main.c文件,该文件定义了工程入口函数,名为app_main。该函数代码如下。- i2c_obj_t i2c0_master;/*** @brief 程序入口* @param 无* @retval 无*/void app_main(void){ uint16_t adcdata; float voltage; esp_err_t ret; ret = nvs_flash_init(); /* 初始化NVS */if (ret ==ESP_ERR_NVS_NO_FREE_PAGES|| ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); } led_init(); /* 初始化LED */ i2c0_master = iic_init(I2C_NUM_0); /* 初始化IIC0 */ spi2_init(); /* 初始化SPI2 */ xl9555_init(i2c0_master); /* 初始化XL9555 */ lcd_init(); /* 初始化LCD */ adc_init(); /* 初始化ADC */ lcd_show_string(30, 50, 200, 16, 16, "ESP32", RED); lcd_show_string(30, 70, 200, 16, 16, "ADC TEST", RED); lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED); lcd_show_string(30, 110, 200, 16, 16, "ADC1_CH7_VAL:", BLUE); lcd_show_string(30, 130, 200, 16, 16, "ADC1_CH7_VOL:0.000V", BLUE); while(1) { adcdata =adc_get_result_average(ADC_ADCX_CHY, 10); /* 显示ADC采样后的原始值 */ lcd_show_xnum(134, 110, adcdata, 5, 16, 0, BLUE); voltage = (float)adcdata * (3.3 / 4096);/* 获取计算后的带小数的实际电压值 */ adcdata = voltage; /* 赋值整数部分给adcx变量 */ lcd_show_xnum(134, 130, adcdata, 1, 16, 0, BLUE);/* 显示电压值的整数部分 */ voltage -= adcdata; /* 把已经显示的整数部分去掉,留下小数部分 */ voltage *= 1000; /* 小数部分乘以1000 */ lcd_show_xnum(150, 130, voltage, 3, 16, 0x80, BLUE); /* 显示小数部分 */ LED_TOGGLE(); /* LED翻转函数 */ vTaskDelay(100); }}
复制代码 从上面的代码中可以看出,在进行完包括ADC的所有初始化工作后,便不断地获取ADC1通道7进行10次转换后经过均值滤波后的结果,并将该原始值显示在LCD上,同时还通过该电压的原始值计算出了电压的模拟量,并在LCD上进行显示。
24.4 下载验证
在完成编译和烧录操作后,可以看到LCD上实时刷新显示着ADC1通道7(IO8引脚)采集到电压的数字量和模拟量,此时可以通过杜邦线给IO8引脚接入不同的电压值(注意共地,且输入电压不能超过3.3V,否则可能损坏开发板),可以看到LCD上显示的电压数字量和模拟量也随之改变。
图24.4.1 SPI LCD显示效果图
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |