ESP32学习笔记【外设篇】-07模数转换器ADC

一、概述

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的局限性

  1. 某些 ADC2 引脚用作搭接引脚(GPIO 0、2、15),因此不能随意使用。以下官方开发套件就是这种情况:
  2. ESP32 DevKitC:由于外部自动编程电路,无法使用 GPIO 0。
  3. ESP-WROVER-KIT:GPIO 0, 2, 4 和 15 由于不同用途的外部连接而无法使用

二、官方API组件

2.1 adc1_config_width

设置 ADC 的分辨率
ESP32学习笔记【外设篇】-07模数转换器ADC_第1张图片

2.2 adc1_config_channel_atten

ESP32学习笔记【外设篇】-07模数转换器ADC_第2张图片

2.3 adc1_get_raw

ESP32学习笔记【外设篇】-07模数转换器ADC_第3张图片

2.4 esp_adc_cal_check_efuse

ESP32学习笔记【外设篇】-07模数转换器ADC_第4张图片

2.5 esp_adc_cal_characterize

ESP32学习笔记【外设篇】-07模数转换器ADC_第5张图片

2.6 esp_adc_cal_raw_to_voltage

ESP32学习笔记【外设篇】-07模数转换器ADC_第6张图片

三、代码逻辑

设置精度、衰减倍数和通道引脚最后一个函数读取即可

  • 设置精度
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日

你可能感兴趣的:(ESP32,stm32,物联网)