ESP32系列--第九篇 ADC的使用

这篇具有很好参考价值的文章主要介绍了ESP32系列--第九篇 ADC的使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、目的

        本篇主要介绍ESP32的ADC功能,ESP32有两个ADC模块,分别为ADC1/ADC2,每个ESP32系列具有的通道数不一样,详情请看下表。

        在WiFi在使用时,ADC2的使用受到一些限制,实际应用场景中一般只使用ADC1即可。

二、介绍

ADC的IO引脚分配

ESP32系列 (下表来自ESP-IDF开发文档)

GPIO

Analog Function

RTC GPIO

Comments

GPIO0

ADC2_CH1

RTC_GPIO11

Strapping pin

GPIO1

TXD

GPIO2

ADC2_CH2

RTC_GPIO12

Strapping pin

GPIO3

RXD

GPIO4

ADC2_CH0

RTC_GPIO10

GPIO5

Strapping pin

GPIO6

SPI0/1

GPIO7

SPI0/1

GPIO8

SPI0/1

GPIO9

SPI0/1

GPIO10

SPI0/1

GPIO11

SPI0/1

GPIO12

ADC2_CH5

RTC_GPIO15

Strapping pin; JTAG

GPIO13

ADC2_CH4

RTC_GPIO14

JTAG

GPIO14

ADC2_CH6

RTC_GPIO16

JTAG

GPIO15

ADC2_CH3

RTC_GPIO13

Strapping pin; JTAG

GPIO16

SPI0/1

GPIO17

SPI0/1

GPIO18

GPIO19

GPIO21

GPIO22

GPIO23

GPIO25

ADC2_CH8

RTC_GPIO6

GPIO26

ADC2_CH9

RTC_GPIO7

GPIO27

ADC2_CH7

RTC_GPIO17

GPIO32

ADC1_CH4

RTC_GPIO9

GPIO33

ADC1_CH5

RTC_GPIO8

GPIO34

ADC1_CH6

RTC_GPIO4

GPI

GPIO35

ADC1_CH7

RTC_GPIO5

GPI

GPIO36

ADC1_CH0

RTC_GPIO0

GPI

GPIO37

ADC1_CH1

RTC_GPIO1

GPI

GPIO38

ADC1_CH2

RTC_GPIO2

GPI

GPIO39

ADC1_CH3

RTC_GPIO3

GPI

        从上表我们可以看到ADC1可以使用的IO引脚为GPIO32-GPIO39总共8个通道。

ESP32S2系列 (下表来自ESP-IDF开发文档)

GPIO

Analog Function

RTC GPIO

Comment

GPIO0

RTC_GPIO0

Strapping pin

GPIO1

ADC1_CH0

RTC_GPIO1

GPIO2

ADC1_CH1

RTC_GPIO2

GPIO3

ADC1_CH2

RTC_GPIO3

GPIO4

ADC1_CH3

RTC_GPIO4

GPIO5

ADC1_CH4

RTC_GPIO5

GPIO6

ADC1_CH5

RTC_GPIO6

GPIO7

ADC1_CH6

RTC_GPIO7

GPIO8

ADC1_CH7

RTC_GPIO8

GPIO9

ADC1_CH8

RTC_GPIO9

GPIO10

ADC1_CH9

RTC_GPIO10

GPIO11

ADC2_CH0

RTC_GPIO11

GPIO12

ADC2_CH1

RTC_GPIO12

GPIO13

ADC2_CH2

RTC_GPIO13

GPIO14

ADC2_CH3

RTC_GPIO14

GPIO15

ADC2_CH4

RTC_GPIO15

GPIO16

ADC2_CH5

RTC_GPIO16

GPIO17

ADC2_CH6

RTC_GPIO17

GPIO18

ADC2_CH7

RTC_GPIO18

GPIO19

ADC2_CH8

RTC_GPIO19

GPIO20

ADC2_CH9

RTC_GPIO20

GPIO21

RTC_GPIO21

GPIO26

SPI0/1

GPIO27

SPI0/1

GPIO28

SPI0/1

GPIO29

SPI0/1

GPIO30

SPI0/1

GPIO31

SPI0/1

GPIO32

SPI0/1

GPIO33

GPIO34

GPIO35

GPIO36

GPIO37

GPIO38

GPIO39

JTAG

GPIO40

JTAG

GPIO41

JTAG

GPIO42

JTAG

GPIO43

GPIO44

GPIO45

Strapping pin

GPIO46

GPI;Strapping pin

        从上表我们可以看到ADC1可以使用的IO引脚为GPIO1-GPIO10总共10个通道。

ESP32S3系列 (下表来自ESP-IDF​​​​​​​开发文档)

GPIO

Analog Function

RTC GPIO

Comment

GPIO0

RTC_GPIO0

Strapping pin

GPIO1

ADC1_CH0

RTC_GPIO1

GPIO2

ADC1_CH1

RTC_GPIO2

GPIO3

ADC1_CH2

RTC_GPIO3

Strapping pin

GPIO4

ADC1_CH3

RTC_GPIO4

GPIO5

ADC1_CH4

RTC_GPIO5

GPIO6

ADC1_CH5

RTC_GPIO6

GPIO7

ADC1_CH6

RTC_GPIO7

GPIO8

ADC1_CH7

RTC_GPIO8

GPIO9

ADC1_CH8

RTC_GPIO9

GPIO10

ADC1_CH9

RTC_GPIO10

GPIO11

ADC2_CH0

RTC_GPIO11

GPIO12

ADC2_CH1

RTC_GPIO12

GPIO13

ADC2_CH2

RTC_GPIO13

GPIO14

ADC2_CH3

RTC_GPIO14

GPIO15

ADC2_CH4

RTC_GPIO15

GPIO16

ADC2_CH5

RTC_GPIO16

GPIO17

ADC2_CH6

RTC_GPIO17

GPIO18

ADC2_CH7

RTC_GPIO18

GPIO19

ADC2_CH8

RTC_GPIO19

USB-JTAG

GPIO20

ADC2_CH9

RTC_GPIO20

USB-JTAG

GPIO21

RTC_GPIO21

GPIO26

SPI0/1

GPIO27

SPI0/1

GPIO28

SPI0/1

GPIO29

SPI0/1

GPIO30

SPI0/1

GPIO31

SPI0/1

GPIO32

SPI0/1

GPIO33

SPI0/1

GPIO34

SPI0/1

GPIO35

SPI0/1

GPIO36

SPI0/1

GPIO37

SPI0/1

GPIO38

GPIO39

GPIO40

GPIO41

GPIO42

GPIO43

GPIO44

GPIO45

Strapping pin

GPIO46

Strapping pin

GPIO47

GPIO48

        从上表我们可以看到ADC1可以使用的IO引脚为GPIO1-GPIO10总共10个通道。

ADC的参考电压

        ESP32默认的参考电压是1.1V(每个芯片间有差异,非精准),所以只能测量0-1.1V的电压;

ADC的量程设置

        为了能够测量更大量程的电压,需要使用其衰减配置;每个通道都可以单独配置

/**
 * @brief ADC attenuation parameter. Different parameters determine the range of the ADC. See ``adc1_config_channel_atten``.
 */
typedef enum {
    ADC_ATTEN_DB_0   = 0,  ///<No input attenumation, ADC can measure up to approx. 800 mV
    ADC_ATTEN_DB_2_5 = 1,  ///<The input voltage of ADC will be attenuated extending the range of measurement by about 2.5 dB (1.33 x)
    ADC_ATTEN_DB_6   = 2,  ///<The input voltage of ADC will be attenuated extending the range of measurement by about 6 dB (2 x)
    ADC_ATTEN_DB_11  = 3,  ///<The input voltage of ADC will be attenuated extending the range of measurement by about 11 dB (3.55 x)
} adc_atten_t;

        每个配置推荐的输入范围

esp32 adc,ESP32,iot,嵌入式硬件​​​​​​​

 

ADC最小化噪声

        1.在输入引脚接一个100nF的陶瓷电容

        2.多次采样取平均

ADC的校准方式

        不同芯片的参考电压不一样(1000mV - 1200mV),所以建议进行硬件校准

/**
 * @brief Type of calibration value used in characterization
 */
typedef enum {
    ESP_ADC_CAL_VAL_EFUSE_VREF = 0,         /**< Characterization based on reference voltage stored in eFuse*/
    ESP_ADC_CAL_VAL_EFUSE_TP = 1,           /**< Characterization based on Two Point values stored in eFuse*/
    ESP_ADC_CAL_VAL_DEFAULT_VREF = 2,       /**< Characterization based on default reference voltage*/
    ESP_ADC_CAL_VAL_EFUSE_TP_FIT = 3,       /**< Characterization based on Two Point values and fitting curve coefficients stored in eFuse */
    ESP_ADC_CAL_VAL_MAX,
    ESP_ADC_CAL_VAL_NOT_SUPPORTED = ESP_ADC_CAL_VAL_MAX,
} esp_adc_cal_value_t;

        ESP32支持ESP_ADC_CAL_VAL_EFUSE_TP/ESP_ADC_CAL_VAL_EFUSE_VREF

        ESP32S2支持ESP_ADC_CAL_VAL_EFUSE_TP

        ESP32S3支持ESP_ADC_CAL_VAL_EFUSE_TP_FIT

        ESP_ADC_CAL_VAL_EFUSE_TP根据EFUSE里面两个采样值进行校准(150mV/850mV)

        ESP_ADC_CAL_VAL_EFUSE_VREF根据EFUSE里面的参考电压校准

        ESP_ADC_CAL_VAL_EFUSE_TP_FIT根据EFUSE里面两个采样点和特性曲线校准

        有些ESP32模组出厂时已经做了校准,我们可以通过工具查看

ADC相关的efuse设置        

$espefuse.py -p /dev/cu.SLAB_USBtoUART adc_info
Connecting......
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting......
Detecting chip type... ESP32
espefuse.py v4.1

=== Run "adc_info" command ===
ADC VRef calibration: 1128mV

        通过espefuse.py adc_info命令我们可以看到我的ESP32模组默认支持VRef校验。

        如果不支持VRef校准输出如下

ADC VRef calibration: None (1100 mV nominal)

         如果支持两点校准,输出如下

ADC VRef calibration: 1149 mV
ADC readings stored in efuse BLK3:
    ADC1 Low reading  (150 mV): 306
    ADC1 High reading (850 mV): 3153
    ADC2 Low reading  (150 mV): 389
    ADC2 High reading (850 mV): 3206

三、实战

        接口说明

        1.检查是否支持指定的校准方式

        esp_err_t esp_adc_cal_check_efuse(esp_adc_cal_value_t value_type);

        2.设置采样量化位数

        esp_err_t adc1_config_width(adc_bits_width_t width_bit);

        3.设置指定通道的衰减

        esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten);

        4.获取指定通道校准特征值

        esp_adc_cal_value_t esp_adc_cal_characterize(adc_unit_t adc_num,
                                             adc_atten_t atten,
                                             adc_bits_width_t bit_width,
                                             uint32_t default_vref,
                                             esp_adc_cal_characteristics_t *chars);

        5.获取指定通道的采样值

        int adc1_get_raw(adc1_channel_t channel);

        6.根据校准特征值获取实际电压值

        uint32_t esp_adc_cal_raw_to_voltage(uint32_t adc_reading, const esp_adc_cal_characteristics_t *chars);

        参考代码

/* ADC1 Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/adc.h"
#include "esp_adc_cal.h"

#define DEFAULT_VREF    1100        //Use adc2_vref_to_gpio() to obtain a better estimate
#define NO_OF_SAMPLES   64          //Multisampling

static esp_adc_cal_characteristics_t *adc_chars;
#if CONFIG_IDF_TARGET_ESP32
static const adc_channel_t channel = ADC_CHANNEL_6;     //GPIO34 if ADC1, GPIO14 if ADC2
static const adc_bits_width_t width = ADC_WIDTH_BIT_12;
#elif CONFIG_IDF_TARGET_ESP32S2
static const adc_channel_t channel = ADC_CHANNEL_6;     // GPIO7 if ADC1, GPIO17 if ADC2
static const adc_bits_width_t width = ADC_WIDTH_BIT_13;
#endif
static const adc_atten_t atten = ADC_ATTEN_DB_0;
static const adc_unit_t unit = ADC_UNIT_1;


static void check_efuse(void)
{
#if CONFIG_IDF_TARGET_ESP32
    //Check if TP is burned into eFuse
    if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP) == ESP_OK) {
        printf("eFuse Two Point: Supported\n");
    } else {
        printf("eFuse Two Point: NOT supported\n");
    }
    //Check Vref is burned into eFuse
    if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_VREF) == ESP_OK) {
        printf("eFuse Vref: Supported\n");
    } else {
        printf("eFuse Vref: NOT supported\n");
    }
#elif CONFIG_IDF_TARGET_ESP32S2
    if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP) == ESP_OK) {
        printf("eFuse Two Point: Supported\n");
    } else {
        printf("Cannot retrieve eFuse Two Point calibration values. Default calibration values will be used.\n");
    }
#else
#error "This example is configured for ESP32/ESP32S2."
#endif
}


static void print_char_val_type(esp_adc_cal_value_t val_type)
{
    if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {
        printf("Characterized using Two Point Value\n");
    } else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {
        printf("Characterized using eFuse Vref\n");
    } else {
        printf("Characterized using Default Vref\n");
    }
}


void app_main(void)
{
    //Check if Two Point or Vref are burned into eFuse
    check_efuse();

    //Configure ADC
    if (unit == ADC_UNIT_1) {
        adc1_config_width(width);
        adc1_config_channel_atten(channel, atten);
    } else {
        adc2_config_channel_atten((adc2_channel_t)channel, atten);
    }

    //Characterize ADC
    adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t));
    esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, width, DEFAULT_VREF, adc_chars);
    print_char_val_type(val_type);

    //Continuously sample ADC1
    while (1) {
        uint32_t adc_reading = 0;
        //Multisampling
        for (int i = 0; i < NO_OF_SAMPLES; i++) {
            if (unit == ADC_UNIT_1) {
                adc_reading += adc1_get_raw((adc1_channel_t)channel);
            } else {
                int raw;
                adc2_get_raw((adc2_channel_t)channel, width, &raw);
                adc_reading += raw;
            }
        }
        adc_reading /= NO_OF_SAMPLES;
        //Convert adc_reading to voltage in mV
        uint32_t voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_chars);
        printf("Raw: %d\tVoltage: %dmV\n", adc_reading, voltage);
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

以上,基本就讲完了ADC1的使用,点赞收藏不可少文章来源地址https://www.toymoban.com/news/detail-744229.html

到了这里,关于ESP32系列--第九篇 ADC的使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 十三、ESP32PS2摇杆(ADC)

    在上下左右操作PS2摇杆的时候,会检测到数据

    2024年02月14日
    浏览(33)
  • ESP32学习笔记09-ADC多通道采集 dma方式传输

    9.1.1特点 高性能。时钟更快,因此采样 速率实现了大幅提升 。 支持 多通道扫描 模式。每个 SAR ADC 的测量规则可见 样式表 。扫描模式可配置为 单通道模式 双通道模式 交替模式。 扫描可由软件或 I2S 总线发起。 支持 DMA,扫描完成即发生中断 9.1.2样式表 通道 分辨率 衰减倍

    2023年04月21日
    浏览(42)
  • 通过ESP32的ADC引脚检测电池电压(并通过均值滤波与软件校准)

    最近有个项目需要用到ESP32的ADC做一下电池电量检测,网上关于这方面的资料写得很模糊,于是自己整理了一下。代码注释写的很详细了,基本能解决你搜这个问题所想要解决的问题,以下是代码简介: 注意,若要使用ADC2请留意该警告 本示例芯片型号:ESP32C3(兼容ESP32其它型

    2024年02月12日
    浏览(46)
  • ESP32S3使用esp-iot-solution SDK开发USBHID鼠标键盘教程

    ​ 手里最近翻到了一个ESP32S3开发板,于是想做个鼠标键盘玩玩,这是我第二次接触ESP32,上一次18年买的吃灰板子至今没上过电。新找到的S3看手册是支持OTG的,按照官方的教程搭建的WSL+VSCODE环境。然而一切准备就绪发现ESP-IDF里面没有USB-HIDdemo。没有demo怎么玩。于是乎查找资

    2024年02月09日
    浏览(45)
  • 《嵌入式 – GD32开发实战指南》第12章 ADC

    开发环境: MDK:Keil 5.30 开发板:GD32F207I-EVAL MCU:GD32F207IK GD32F2系列有 3 个逐次逼近型的ADC,精度为 12 位,有18个多路复用通道,可以转换来自16个外部通道和2个内部通道的模拟信号。其中ADC0 和 ADC1都有 16 个外部通道, ADC2 根据 CPU 引脚的不同通道数也不同,一般都有8 个外部

    2023年04月08日
    浏览(61)
  • 第九篇 华为云Iot SDK的应用(一)上报属性&接收命令

    1.初始化SDK 2.绑定连接配置信息 3.连接服务器 4.上报属性 5.接收命令 1.实现效果 🔖通过串口命令控制灯光,并且实时上报四个灯的状态(ON/OFF);接收下发命令,控制相应的灯并实时上报。 1.华为云MQTT SDK使用(一) 2.参考代码

    2024年02月21日
    浏览(34)
  • 蓝桥杯嵌入式STM32 G431 hal库开发速成——ADC与DAC

    模数转换器(ADC):它将模拟信号转换为单片机能够处理的数字信号。在很多应用中,比如温度传感器、压力传感器等,信号最初都是模拟形式的。ADC 读取这些模拟信号,然后将它们转换为数字形式,以便单片机可以读取和处理。 数模转换器(DAC):它执行相反的操作,将

    2024年02月01日
    浏览(58)
  • [嵌入式软件][启蒙篇][仿真平台] STM32F103实现串口输出输入、ADC采集

    上一篇:[嵌入式软件][启蒙篇][仿真平台] STM32F103实现LED、按键 学C语言时,使用的printf()函数,就是通过串口打印出来的。 跟外部器件通信,比如GPS模块、蓝牙模块、wifi模块; 两个开发板之间通信,制定私有协议。 PC电脑通信,使用上位机显示数据或控制下位机。 操作:打

    2024年01月22日
    浏览(65)
  • Proteus使用STM32F103系列芯片仿真ADC电压总是为0问题解答

    STM32F103芯片有一组ADC参考电压端口  对应到Proteus中,发现原理图上并没有但是在“配置供电网”中存在 可以看出,VSSA与VDDA同为3.3V,这就导致采集到的电压没有0电位参考,所以需要将 VSSA 转移到 GND 组   此时再允许正确的ADC程序就可以采集到正确的电压了      

    2024年02月13日
    浏览(48)
  • 通过ESP32实现实际IoT应用:高级TCP/UDP实现

    第1部分:使用ESP32构建强大的TCP服务器和客户端 介绍 欢迎来到我们关于ESP32上的实际应用和高级主题的详细系列的第一部分。我们首先关注开发TCP(传输控制协议)服务器和客户端,这是物联网中网络通信的基石。本节将涵盖TCP通信的基本知识,如何在ESP32上设置TCP服务器和

    2024年02月02日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包