一、概述
ESP32集成两个12位逐次逼近型模数转换器(SARADC),共支持18个模拟输入通道:
模式 | 适用场景 |
---|---|
单次采样模式 | 低频采样(如传感器读取) |
连续采样模式 | 高频采样(需DMA支持) |
二、API说明
关键头文件:
driver/adc.h
driver/adc_common.h
esp_adc_cal.h
adc1_config_width()
esp_err_t adc1_config_width(adc_bits_width_t width);
typedef enum {
ADC_WIDTH_BIT_9 = 0, // 9位(量程0~511)
ADC_WIDTH_BIT_10 = 1, // 10位(0~1023)
ADC_WIDTH_BIT_11 = 2, // 11位(0~2047)
ADC_WIDTH_BIT_12 = 3 // 12位(0~4095,推荐)
} adc_bits_width_t;
adc1_config_channel_atten()
esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten);
衰减枚举 | 量程(VDD=3.3V) | 适用场景 |
---|---|---|
ADC_ATTEN_DB_0 |
0~0.8V | 精密传感器(如光敏) |
ADC_ATTEN_DB_2_5 |
0~1.1V | 低电压信号 |
ADC_ATTEN_DB_6 |
0~1.35V | 中等电压 |
ADC_ATTEN_DB_11 |
0~2.6V | 电池电压(需分压) |
adc1_get_raw()
int adc1_get_raw(adc1_channel_t channel);
esp_adc_cal_characterize()
esp_adc_cal_value_t esp_adc_cal_characterize(
adc_unit_t unit,
adc_atten_t atten,
adc_bits_width_t bitwidth,
uint32_t default_vref,
esp_adc_cal_characteristics_t *chars
);
default_vref
(默认1100mV)if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {
printf("使用eFuse两点校准\n");
} else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {
printf("使用eFuse Vref校准\n");
} else {
printf("使用默认Vref\n"); // 精度最低
}
esp_adc_cal_raw_to_voltage()
uint32_t esp_adc_cal_raw_to_voltage(
uint32_t adc_reading,
const esp_adc_cal_characteristics_t *chars
);
adc1_get_raw()
的原始值 + 校准结构体uint32_t voltage = esp_adc_cal_raw_to_voltage(raw_val, &adc_chars);
printf("电压值: %dmV\n", voltage); // 输出如 "电压值: 1234mV"
adc2_get_raw()
esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width, int *raw_out);
ESP_ERR_INVALID_STATE
表示被Wi-Fi占用int raw_val;
esp_err_t ret = adc2_get_raw(ADC2_CHANNEL_7, ADC_WIDTH_BIT_12, &raw_val);
if (ret == ESP_ERR_INVALID_STATE) {
// 需延迟重试或关闭Wi-Fi
}
hall_sensor_read()
int hall_sensor_read(void);
adc1_config_width(ADC_WIDTH_BIT_12); // 需先配置位宽
int hall_val = hall_sensor_read(); // 返回值受外部磁场影响
adc_vref_to_gpio()
esp_err_t adc_vref_to_gpio(adc_unit_t unit, gpio_num_t gpio);
噪声抑制
uint32_t sum = 0;
for (int i=0; i<64; i++) {
sum += adc1_get_raw(channel);
}
int avg = sum >> 6; // 等效除以64
分压电路设计
锂电池检测典型电路:
VBAT+ ─ 20kΩ ──┬── 10kΩ ── GND
│
└─ 100nF ── GND
│
└─ GPIO35 (ADC1_CH7)
六、编程流程
1. 位宽配置
typedef enum {
ADC_WIDTH_BIT_9 = 0, // 9位精度
ADC_WIDTH_BIT_10 = 1, // 10位精度
ADC_WIDTH_BIT_11 = 2, // 11位精度
ADC_WIDTH_BIT_12 = 3 // 12位精度(默认)
} adc_bits_width_t;
2. 衰减系数与量程
衰减值 | 量程范围 (VDD=3.3V) |
---|---|
ADC_ATTEN_DB_0 |
0 ~ 0.8V |
ADC_ATTEN_DB_2_5 |
0 ~ 1.1V |
ADC_ATTEN_DB_6 |
0 ~ 1.35V |
ADC_ATTEN_DB_11 |
0 ~ 2.6V |
3. 通道映射
// ADC1通道与GPIO对应
ADC1_CHANNEL_0 → GPIO36
ADC1_CHANNEL_4 → GPIO32 // 注意索引顺序
// ADC2通道示例
ADC2_CHANNEL_0 → GPIO4
ADC2_CHANNEL_9 → GPIO26
七、应用实例
#include
void read_adc1() {
adc1_config_width(ADC_WIDTH_BIT_12);
adc1_config_channel_atten(ADC1_CHANNEL_7, ADC_ATTEN_DB_0);
int val = adc1_get_raw(ADC1_CHANNEL_7); // 读取GPIO35
printf("ADC1 Value: %d\n", val);
}
#include
void read_adc2() {
int raw_val;
adc2_config_channel_atten(ADC2_CHANNEL_7, ADC_ATTEN_DB_11);
esp_err_t ret = adc2_get_raw(ADC2_CHANNEL_7, ADC_WIDTH_BIT_12, &raw_val);
if (ret == ESP_OK) {
printf("ADC2 Value: %d\n", raw_val);
} else if (ret == ESP_ERR_INVALID_STATE) {
printf("Error: Wi-Fi占用ADC2!\n"); // 处理冲突
}
}
#include "esp_adc_cal.h"
void adc_calibration() {
esp_adc_cal_characteristics_t adc_chars;
esp_adc_cal_value_t cal_type = esp_adc_cal_characterize(
ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12, 1100, &adc_chars
);
int raw = adc1_get_raw(ADC1_CHANNEL_5);
uint32_t voltage = esp_adc_cal_raw_to_voltage(raw, &adc_chars);
printf("Voltage: %dmV\n", voltage);
}
#include
void read_hall_sensor() {
adc1_config_width(ADC_WIDTH_BIT_12);
int hall_val = hall_sensor_read(); // 自动使用GPIO36/39
printf("Hall Effect: %d\n", hall_val);
}
关键注意事项
ESP_ERR_INVALID_STATE
本文基于ESP-IDF v4.4+编写,完整示例见ESP-IDF示例目录:
examples/peripherals/adc
examples/peripherals/adc2