一、概述
ESP32 有 2 个 12 位的 ADC,共计 18 通道,ADC2 比较特殊的一点就是:ADC2 和 wifi 共用,wifi 的优先级更高,所以 ADC2 只有在 WIFI 模块不用的情况下可以使用。
ESP32 的 18 个通道的 ADC 如下:
- ADC1:
- 8通道:GPIO32 - GPIO39
- ADC2:
- 10个通道:GPIO0、GPIO2、GPIO4、GPIO12-GPIO15、GOIO25-GPIO27
ESP32中ADC的局限性
- 某些 ADC2 引脚用作搭接引脚(GPIO 0、2、15),因此不能随意使用。以下官方开发套件就是这种情况:
- ESP32 DevKitC:由于外部自动编程电路,无法使用 GPIO 0。
- ESP-WROVER-KIT:GPIO 0, 2, 4 和 15 由于不同用途的外部连接而无法使用
二、官方API组件
2.1 adc1_config_width
设置 ADC 的分辨率
2.2 adc1_config_channel_atten
2.3 adc1_get_raw
2.4 esp_adc_cal_check_efuse
2.5 esp_adc_cal_characterize
2.6 esp_adc_cal_raw_to_voltage
三、代码逻辑
设置精度、衰减倍数和通道引脚最后一个函数读取即可
- 设置精度
esp_err_t adc1_config_width(adc_bits_width_t width_bit);
- 参数
typedef enum {
ADC_WIDTH_BIT_9 = 0, /*!< ADC capture width is 9Bit*/
ADC_WIDTH_BIT_10 = 1, /*!< ADC capture width is 10Bit*/
ADC_WIDTH_BIT_11 = 2, /*!< ADC capture width is 11Bit*/
ADC_WIDTH_BIT_12 = 3, /*!< ADC capture width is 12Bit*/
ADC_WIDTH_MAX,
} adc_bits_width_t;
- ADC1衰减倍数(参考电压)和通道
esp_err_t adc1_config_channel_atten
(adc1_channel_t channel, adc_atten_t atten);
- ADC1参数
typedef enum {
ADC1_CHANNEL_0 = 0, /*!< ADC1 channel 0 is GPIO36 */
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;
typedef enum {
ADC_ATTEN_DB_0
/*!< ADC1 channel 1 is GPIO37 */
/*!< ADC1 channel 2 is GPIO38 */
/*!< ADC1 channel 3 is GPIO39 */
/*!< ADC1 channel 4 is GPIO32 */
/*!< ADC1 channel 5 is GPIO33 */
/*!< ADC1 channel 6 is GPIO34 */
/*!< ADC1 channel 7 is GPIO35 */
= 0,
ADC_ATTEN_DB_2_5 = 1,//表示参考电压为 1.1V
ADC_ATTEN_DB_6 = 2,//表示参考电压为 1.5V
ADC_ATTEN_DB_11 = 3, //表示参考电压为 2.2V
ADC_ATTEN_MAX,//表示参考电压为 3.9V
} adc_atten_t;
一般不用ADC2因为esp32作为wfi模块主要使用wfi功能
- 读取ADC函数
对于 ADC1,读取函数有两个,他们的参数和返回值是完全一样的,二选一使用即可,定义如下:
int adc1_get_voltage(adc1_channel_t channel);
int adc1_get_raw(adc1_channel_t channel);
四、例程解析
定义通道
#define ADC1_TEST_CHANNEL ADC1_CHANNEL_6
adc初始化
void adc_Init()
{ //12位分辨率
adc1_config_width(ADC_WIDTH_12Bit); //设置通道6和1.1V参考电压
adc1_config_channel_atten(ADC1_TEST_CHANNEL,ADC_ATTEN_0db);
}
主函数
void app_main(){
int read_raw;
char adc_buff[50] = {0};
adc_Init(); //显示屏初始化
while (1) {
read_raw = adc1_get_raw(ADC1_TEST_CHANNEL); //采集ADC
//ADC的结果转换成电压 //参考电压是1.1V,所以是1100mV,12位分辨率,所以是4096
vTaskDelay(10);
}
}
五、总结
- ADC读取操作简单,难在准确稳定
- 由Lee1989写于2021年09月12日