ESP32S3学习——ADC
芯片:esp32s3
开发环境:espidfv4.4
一、官网相关资料
1)、ESP32-S3集成了2个SAR(逐次逼近寄存器)ADC,共支持20个测量通道(模拟启用引脚)。
ADC1:
-
10 channels: GPIO1 - GPIO10
ADC2:
-
10 channels: GPIO11 - GPIO20
2)、ADC衰减
Vref是ESP32-S3 ADC内部用于测量输入电压的参考电压。ESP32-S3 ADC可以测量从0V到Vref的模拟电压。在不同的芯片中,Vref变化,中值为1.1V。为了转换大于Vref的电压,输入电压可以在输入到ADC之前被衰减。有4种可用的衰减选项,衰减越高,可测量的输入电压可能越高。
Attenuation | Measurable input voltage range |
---|---|
ADC_ATTEN_DB_0 | 0 mV ~ 950 mV |
ADC_ATTEN_DB_2_5 | 0 mV ~ 1250 mV |
ADC_ATTEN_DB_6 | 0 mV ~ 1750 mV |
ADC_ATTEN_DB_11 | 0 mV ~ 3100 mV |
3)、ADC转换 ADC转换是将输入的模拟电压转换为数字值。由ADC驱动器API提供的ADC转换结果是原始数据。单读模式下ESP32-S3 ADC原始结果的分辨率为12位。
计算公式:
Vout = Dout * Vmax / Dmax (1)
4)、对于带有eFuse ADC校准位的板,可以使用esp_ADC_cal_raw_to_voltage()来获得校准的转换结果。这些结果代表实际电压(mV)。不需要通过公式(1)来变换这些数据。如果在没有eFuse ADC校准位的板上使用ADC校准API,将生成警告。看见
5)、由于Wi-Fi也使用ADC2模块,ADC2_get_raw()的读取操作可能会在esp_wifi_start()和esp_wify_stop()之间失败。
二、配置流程
1)读取之前应配置ADC,配置位宽和衰减,上文有说 对于ADC1,通过调用函数ADC1_config_width()和ADC1_conconfig_channel_atten()来配置所需的精度和衰减。 对于ADC2,通过ADC2_config_channel_atten()配置衰减。每次读取时都会配置ADC2的读取宽度。嘛意思
2)、读取adc值
-
adc2_get_raw()adc的读取函数中应有位宽参数
3)示例工程
单读取模式ADC示例可以在ESP-IDF示例的peripherals/ADC/Single_Read目录中找到
4)软硬件校准
不同芯片参考电压存在误差(1000mv-1200mv)
1、硬件校准
巴拉巴巴拉看不懂
2、软件校准
巴拉巴拉,先跳过
5)一些用于指定ADC通道的GPIO编号的宏
-
ADC1_CHANNEL_0_GPIO_NUM
is the GPIO number of ADC1 channel 0. -
ADC1_GPIOn_CHANNEL
is the ADC1 channel number of GPIO n.
三、上手敲代码
1)头文件Header File
2)先看看官方历程,这里是adc1
1、readme:如果打印出以下警告,则表示需要校准的eFuse位没有在您的板上正确烧写。将跳过校准。只打印原始数据。
```
W (300) ADC SINGLE: eFuse not burnt, skip calibration
I (1310) ADC2_CH0: raw data: 2715
```
2、app_main配置过程
1.adc_calibration_init():adc校准,前文提到的软件校准,固定的东西,回头再仔细看下
esp_adc_cal_check_efuse(ADC_EXAMPLE_CALI_SCHEME)
esp_adc_cal_characterize(ADC_UNIT_1, ADC_EXAMPLE_ATTEN, ADC_WIDTH_BIT_DEFAULT, 0, &adc1_chars);
esp_adc_cal_characterize(ADC_UNIT_2, ADC_EXAMPLE_ATTEN, ADC_WIDTH_BIT_DEFAULT, 0, &adc2_chars);
2、adc1_config_width(ADC_WIDTH_BIT_DEFAULT):位宽设置,默认为soc最大位宽,这里是12bit
3、adc1_config_channel_atten(ADC1_EXAMPLE_CHAN0, ADC_EXAMPLE_ATTEN):在ADC1上设置特定通道的衰减,并配置其相关的GPIO引脚复用器。
adc2_config_channel_atten(ADC2_EXAMPLE_CHAN0, ADC_EXAMPLE_ATTEN)
4、adc1_get_raw(ADC1_EXAMPLE_CHAN0):获取ADC1_CHANNEL_2adc值
5、if (cali_enable) {
voltage = esp_adc_cal_raw_to_voltage(adc_raw[0][0], &adc1_chars);
ESP_LOGI(TAG_CH[0][0], "cali data: %d mV", voltage);
}
如果有校准,使用该函数可以直接获取电压值
6、adc2的使用有一点区别,需要添加位宽参数
adc2_get_raw(ADC2_EXAMPLE_CHAN0, ADC_WIDTH_BIT_DEFAULT, &adc_raw[1][0]);
voltage = esp_adc_cal_raw_to_voltage(adc_raw[1][0], &adc2_chars);
同样的直接获取电压值
7、io对应关系在adc.h中定义