ESP32模数转换 ADC(光感检测)

本文介绍了ESP32 ADC的功能及使用方法,包括光敏电阻和显示屏的应用。详细讲解了ESP32 ADC配置与读取过程,并提供了代码示例。

这个实验的功能演示 ESP32 ADC 的使用方法。 这个实验的代码为工程“3_11_adc”目录。

3.11.1. 实验内容

(1) 学习 ESP32 ADC 功能的使用
(2) 学习光敏电阻的使用
(3) 学习显示屏的使用

3.11.2. 硬件设计和原理

打开我们提供的电路图,在文件:\原理图\ESP32 开发板电路图 V1.3.pdf 里,
光敏电阻的特性是有光照的时候,电阻会变小。上图中 R15 是光敏电阻,在没有光照射到光敏电阻的 情况下,R15 的阻值是无限大,ADC 采集到最大的电压也就是 R9 和 R10 的分压,即是 1.06V,当有光照射 到光敏电阻的情况下,光照越强,ADC 采集到的电压越低。
从上面的原理图可以看出,光敏电阻的 ADC 采集通过拨码开关后,是接在 IO34 上的,使用 ADC 光敏 时一定要打开底板上的拨码开关7,如下图:

ESP32 有 2 个 12 位的 ADC,共计 18 通道,ADC2 比较特殊的一点就是:ADC2 和 wifi 共用,wifi 的优 先级更高,所以 ADC2 只有在 WIFI 模块不用的情况下可以使用。
ESP32 的 18 个通道的 ADC 如下:
在这里插入图片描述

打开我们提供的另一个文档:.\手册和文档\ESP32-S_产品规格书.pdf,关于管脚定义部分,
在这里插入图片描述

通过上图,我们知道接光敏电阻的 IO34 是接在 ADC1 的第 6 通道上,写代码的时候我们对 ADC1 的第
6 通道编程,就可以取出光照强度。

3.11.3. ESP32 ADC 函数介绍

 配置 ADC
对于 ADC1,通过调用函数 adc1_config_width() 和 adc1_config_channel_atten() 来配置所需的精度和衰减。
函数定义:
esp_err_t adc1_config_width(adc_bits_width_t width_bit); 参数说明:
adc_bits_width_t width_bit:设置 ADC 的分辨率,这是一个枚举,具体定义在后面有说明 返回值:ESP_OK(成功)。

typedef enum {
ADC_WIDTH_BIT_9 = 0, //ADC 的分辨率是 9 位,即最大值为 2 的 9 次方,即 512
ADC_WIDTH_BIT_10 = 1, //ADC 的分辨率是 10 位,即最大值为 2 的 10 次方,即 1024
ADC_WIDTH_BIT_11 = 2, //ADC 的分辨率是 11 位,即最大值为 2 的 11 次方,即 2048
ADC_WIDTH_BIT_12 = 3, //ADC 的分辨率是 12 位,即最大值为 2 的 12 次方,即 4096 ADC_WIDTH_MAX,
} adc_bits_width_t;

函数定义:
esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten); 参数说明:
adc1_channel_t channel:配置 ADC 的通道,这是一个枚举,具体定义在后面有说明 adc_atten_t atten:配置 ADC 的参考电压,这是一个枚举,具体定义在后面有说明
返回值:ESP_OK(成功)。

typedef enum {
ADC1_CHANNEL_0 = 0, /*!< ADC1 channel 0 is 
ADC1_CHANNEL_1,
ADC1_CHANNEL_2, ADC1_CHANNEL_3, ADC1_CHANNEL_4, ADC1_CHANNEL_5, ADC1_CHANNEL_6, ADC1_CHANNEL_7, ADC1_CHANNEL_MAX,
} adc1_channel_t; 
ADC_ATTEN_DB_2_5 = 1,
ADC_ATTEN_DB_6	= 2,
ADC_ATTEN_DB_11 = 

对于 ADC2,通过 adc2_config_channel_atten() 配置衰减. 每次读取时都会配置 ADC2 的读取宽度。
函数定义:
esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten); 参数说明:
adc2_channel_t channel:配置 ADC 的通道,这是一个枚举,具体定义在后面有说明 adc_atten_t atten:配置 ADC 的参考电压,这是一个枚举,在 ADC1 配置函数里有说明
返回值:ESP_OK(成功)。

typedef enum {
ADC2_CHANNEL_0 = 0, /*!< ADC2 channel 0 is GPIO4 */ ADC2_CHANNEL_1,	/*!< ADC2 channel 1 is GPIO0 */ ADC2_CHANNEL_2,	/*!< ADC2 channel 2 is GPIO2 */ ADC2_CHANNEL_3,	/*!< ADC2 channel 3 is GPIO15 */ ADC2_CHANNEL_4,	/*!< ADC2 channel 4 is GPIO13 */ ADC2_CHANNEL_5,	/*!< ADC2 channel 5 is GPIO12 */
ADC2_CHANNEL_6, /*!< ADC2 channel 6 is GPIO14 */ ADC2_CHANNEL_7, /*!< ADC2 channel 7 is GPIO27 */ ADC2_CHANNEL_8, /*!< ADC2 channel 8 is GPIO25 */ ADC2_CHANNEL_9, /*!< ADC2 channel 9 is GPIO26 */ ADC2_CHANNEL_MAX,
} adc2_channel_t;

 读取 ADC
对于 ADC1,读取函数有两个,他们的参数和返回值是完全一样的,二选一使用即可,定义如下:
int adc1_get_voltage(adc1_channel_t channel); int adc1_get_raw(adc1_channel_t channel); 参数说明:
adc1_channel_t channel:配置 ADC 的通道,这是一个枚举,在 ADC1 配置函数里有说明 返回值:采样到通道的 ADC 值。

对于 ADC2,使用下面的函数读取 ADC 值,定义如下:
esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int* raw_out); 参数说明:
adc2_channel_t channel:配置 ADC2 的通道号,这是一个枚举,在 ADC2 配置函数里有说明 adc_bits_width_t width_bit:设置 ADC 的分辨率
int* raw_out:这是一个返回值,表示读取到的 ADC 值 返回值:ESP_OK(成功),ESP_ERR_TIMEOUT(wifi 正在使用)。
3.11.4. 代码讲解

使用 vs code 展开本实验的工程目录,如下图:
在这里插入图片描述

我们的这个实验,ADC 采集的代码是写在源文件 app_main.c 里,components 文件夹是关于 LCD 的驱 动代码,LCD 显示屏在 3.4 章有比较详情的讲解。
我们打开 app_main.c,首先看 ADC 的初始化:

void adc_Init()
{
//12 位分辨率 adc1_config_width(ADC_WIDTH_12Bit);

99

//设置通道 6 和 1.1V 参考电压 adc1_config_channel_atten(ADC1_TEST_CHANNEL,ADC_ATTEN_0db);
}
其中 ADC1_TEST_CHANNEL 定义如图:
//ADC 所接的通道
#define ADC1_TEST_CHANNEL ADC1_CHANNEL_6

接着看 app_main()主函数,函数里初始化了 LCD 和 ADC,然后通过 while(1)周期读取 ADC 的值,代 码如下:

//用户函数入口,相当于 main 函数
void app_main()
{
int read_raw;
char adc_buff[50]={0};

//显示屏初始化 Lcd_Init(); adc_Init();

//显示屏提示信息
.......略......;
while(1)
{
read_raw=adc1_get_voltage(ADC1_TEST_CHANNEL);//采集 ADC

//ADC 的结果转换成电压
//参考电压是 1.1V,所以是 1100mV,12 位分辨率,所以是 4096 sprintf(adc_buff, "adc=%d,%dmv", read_raw, (read_raw*1100)/4096); Gui_DrawFont_GBK16(6,90,VIOLET,BLACK,(u8 *)adc_buff);//显示屏输出 vTaskDelay(10);
}
}

3.11.5. 实验过程

配置下载串口、波特率、编绎和程序下载的详细过程请往回看 3.1.4,在这个实验里都是一笔带过。 (1) 把开发板通过 USB 线接到电脑上,通过设备管理器查看生成的串口。开发板在我们演示电脑上生
成的是 COM3。
(2) 在 menuconfig 菜单里配置下载程序串口。提供的例程配置的串口是 COM3,波特率为 921600。
(3) 通过 make all 编绎工程。
(4) 当编绎通过之后,使用命令 make flash 把程序下载到开发板上。或者参考 2.3.2 节,使用工具 下载。
(5) 按下开发板的复位键,让程序运行起来,观察显示屏最后一行的显示,用于遮挡光敏传感器观察 LCD 变化。如果没有LCD,串口也有输出。

最后推荐一款开发套件,可以手淘扫码查看。
在这里插入图片描述

### ESP32 ADC (模数转换) 功能概述 ESP32 配备有高精度的ADC模块,能够将模拟信号转换成数字信号。该特性对于传器数据采集至关重要,例如温度、湿度或照强度测量等应用场合[^2]。 ### 使用方法详解 #### Arduino平台下的ADC使用 在Arduino平台上操作ESP32ADC非常简便。只需定义所使用的引脚编号并调用`analogRead()`函数即可完成一次简单的读取过程。此方式适用于大多数基础应用场景下快速获取单次采样的需求。 ```cpp const int pinAdc = 34; void setup(){ Serial.begin(115200); } void loop(){ int val = analogRead(pinAdc); // Read the value from ADC pin float voltage = val / 4095.0 * 3.3; // Convert to voltage, assuming a full-scale range of 3.3V and resolution is 12-bit. Serial.print("Value: "); Serial.println(val); delay(1000); } ``` 上述代码展示了如何利用Arduino IDE编写程序来读取指定GPIO端口处输入的模拟量,并将其转化为实际物理意义中的电压值显示出来。 #### MicroPython环境下的ADC编程 当采用MicroPython作为开发工具链时,则需借助内置库`machine.ADC`来进行初始化设置以及后续的数据处理工作。下面给出了一段完整的实例说明文档中提到的方法[^3]: ```python from machine import Pin, ADC adc_pin = ADC(Pin(34)) # Create an ADC object associated with GPIO34. def read_adc_voltage(): raw_value = adc_pin.read() voltage = raw_value / 4095 * 3.3 # Assuming Vref=3.3v & Resolution=12bit return round(voltage, 2) while True: print('Voltage:', str(read_adc_voltage())+'V') time.sleep_ms(1000) ``` 这段脚本实现了周期性的从选定管脚收集信息并将结果呈现给用户查看的功能。 #### 基于ESP-IDF框架的高级配置选项 针对更复杂的要求比如多路同步采样或是高速连续监测任务,则推荐基于Espressif官方提供的组件级API接口——即ESP-IDF SDK进行深入定制化设计。这里提供了一个关于构建持续型ADC会话的基础模板[^4]: ```c #include "driver/adc.h" #include "esp_adc_cal.h" #define DEFAULT_VREF 1100 //Use calibrated vref based on efuse readings or use default one as fallback option static esp_err_t init_continuous_mode(void){ adc_continuous_handle_t handle; /* Initialize configuration structure */ adc_continuous_config_t config = { .pattern_num = 1, .sample_freq_hz = 10000UL, // Set sampling frequency here .conv_mode = ADC_CONV_SINGLE_UNIT_1,// Choose conversion mode according to your needs .format = ADC_DIGI_OUTPUT_FORMAT_TYPE1// Specify DMA output data format type }; /* Configure single channel pattern */ static const adc_digi_pattern_config_t pat[] = {{ .atten = ADC_ATTEN_DB_0, // Signal attenuation level selection .channel = ADC_CHANNEL_6, // Select target input channel number .unit = ADC_UNIT_1, // Indicate which ADC unit this belongs to .bit_width = SOC_ADC_DIGI_MAX_BITWIDTH // Define desired bit width for each sample point }}; config.adc_pattern = pat; /* Install driver */ if (adc continuous new (&config,&handle)!=ESP_OK)return ESP_FAIL; /* Start continuous conversion process */ if (adc_continuous_start(handle)!=ESP_OK)return ESP_FAIL; return ESP_OK; } /* Callback function used when receiving converted samples via interrupt service routine(ISR)*/ static void IRAM_ATTR example_adc_intr_handler(uintptr_t arg){ size_t length; uint16_t* buffer=(uint16_t*)arg; while(true){ if(!adc_continuous_read(arg,(char**)(&buffer),&length)){ break; } printf("Sampled Value:%u\n",*(buffer)); } } ``` 以上C语言片段描述了怎样通过注册回调机制配合中断服务例程的方式高效地管理大批量实时产生的数字化样本流,并确保整个流程稳定可靠运行。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bytechip

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值