esp32学习笔记(4)——adc

本文详细介绍了ESP32的ADC特性,包括ADC1和ADC2的通道、衰减设置、转换原理。讲解了如何配置ADC位宽、衰减,并提供了ADC单次读取和通过DMA连续读取的接口函数介绍。还给出了ADC转换电压的计算方法以及ADC校准的相关操作。最后,提供了一个ADC+DMA的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

ADC即模拟数字转换器(Analog-to-digital converter)是用于将模拟形式的连续信号转换数字形式的离散信号的一类设备。一个模拟数字转换器可以提供信号用于测量。与之相对的设备成为数字模拟转换器。
例如温度、压力、声音或者图像等,需要转换成更容易储存、处理和发射的数字形式。那就可以用到ADC了


提示:以下是本篇文章正文内容,下面案例可供参考

一、ESP32 ADC相关介绍

一些 ADC2 引脚用作捆绑引脚(GPIO 0、2、15),因此不能自由使用。
ESP32 DevKitC:由于外部自动编程电路,GPIO 0 无法使用。
ESP-WROVER-KIT:GPIO 0、2、4 和 15 不能使用,因为用于不同目的的外部连接。
由于 ADC2 模块也被 Wi-Fi 使用,因此它们一起使用时只有一个可以抢占,这意味着adc2_get_raw()可能会被阻塞直到 Wi-Fi 停止

ESP32 集成了 2 个 SAR(逐次逼近寄存器)ADC,总共支持 18 个测量通道(模拟使能引脚)。
ADC1,8通道:GPIO32 - GPIO39
ADC2,10个通道:GPIO0、GPIO2、GPIO4、GPIO12 - GPIO15、GOIO25 - GPIO27
以下介绍通过ADC1进行介绍
2、ADC衰减
Vref 是 ESP32 ADC 内部用于测量输入电压的参考电压。ESP32 ADC 可以测量从 0 V 到 Vref 的模拟电压。在不同的芯片中,Vref 不同,中位数为 1.1 V。为了转换大于 Vref 的电压,可以在输入 ADC 之前对输入电压进行衰减。有 4 种可用的衰减选项,衰减越高,可测量的输入电压就越高。
在这里插入图片描述
3、ADC 转换
ADC 转换是将输入模拟电压转换为数字值。ADC 驱动程序 API (adc1_get_raw())提供的 ADC 转换结果是原始数据。Single Read 模式下 ESP32 ADC 原始结果的分辨率为 12 位。
如果根据ADC采集的原始数据来计算电压那可以用Vout(输出电压)=Dout(输出的数据)*Vmax(最大测量电压)/Dmax(最大输出数据)
ps:如果是带有ADC校准位的板子可以直接调用esp_adc_cal_raw_to_voltage()来直接读取输出电压,单位为mv
4、ADC 单次读取
在配置好位宽adc1_config_width()和衰减adc1_config_channel_atten()之后就可以直接调用adc1_get_raw(),读取结果了;值得说明的是官方也提供给了从ULP直接读取ADC1通道的结果,但是这个要在配置的时候调用adc1_ulp_enable()来使能ULP

二、使用步骤

1.接口函数介绍

(1)设置通道衰减

esp_err_t adc1_config_channel_atten(adc1_channel_t channel,adc_atten_t atten )

第一个参数是设置ADC通道,第二个参数是设置衰减等级;默认衰减是0dB;通过官方给的衰减设置可以看到,衰减设置的越大,那么可采集的电压范围就越大(通过对输入电压进行衰减)
返回值:
ESP_OK 成功
ESP_ERR_INVALID_ARG 参数错误
在这里插入图片描述

在这里插入图片描述
(2)配置ADC的捕获位宽

esp_err_t adc1_config_width( adc_bits_width_t width_bit )

参数:ADC1 的位捕获宽度
返回值:
ESP_OK 成功
ESP_ERR_INVALID_ARG 参数错误
在这里插入图片描述

(3)读取单个通道上的ADC数据

int adc1_get_raw( adc1_channel_t channel)

返回
-1:参数错误
其他:ADC1 通道读数。
参数
channel: ADC1 通道读取

(4)初始化数字ADC

esp_err_t adc_digi_initialize(const adc_digi_init_config_t *init_config )

参数:数字ADC的初始化配置adc_digi_init_config_t 在这个结构体里面;
返回:

    • ESP_ERR_INVALID_ARG 参数错误
    • ESP_ERR_NOT_FOUND 没有找到中断空闲
    • ESP_ERR_NO_MEM 内存不足
    • ESP_OK 成功
      在这里插入图片描述
      结构体中参数依次是
      1)转换后的数据可以存储的最大长度。
      2)在一个中断中可以转换的数据字节数
      3)待初始化的ADC1通道列表。
      4)需要初始化的ADC2通道列表。

(5)通过 DMA 从数字 ADC 读取字节。

esp_err_t adc_digi_read_bytes(uint8_t *buf, uint32_t length_max, uint32_t *out_length, uint32_t timeout_ms);

[out] buf:从 ADC 读取的缓冲区。
[in] length_max:从 ADC 读取的预期数据长度。
[out] out_length:从 ADC 读取的数据的实际长度。
[in] timeout_ms:等待数据的时间,以毫秒为单位。
返回
ESP_ERR_INVALID_STATE 驱动状态无效。通常这意味着 ADC 采样率快于任务处理率。
ESP_ERR_TIMEOUT 操作超时
ESP_OK 成功
(6)启动数字ADC和 DMA

esp_err_t adc_digi_start(void);

返回
ESP_ERR_INVALID_STATE 驱动状态无效。
ESP_OK 成功
(6)设置数字控制器

esp_err_t adc_digi_controller_configure(const adc_digi_configuration_t *config);

返回值:
ESP_ERR_INVALID_STATE 驱动状态无效。
ESP_ERR_INVALID_ARG 如果参数组合无效。
ESP_OK 成功
参数为adc_digi_configuration_t 结构体
在这里插入图片描述
结构体中参数依次是
1)限制ADC转换的时间,转换完成后是否停止
2)限制ADC转换触发器上限1-255
3)ADC通道数
4)初始化结构体配置参数
5)采样频率611Hz ~ 83333Hz
6)ADC DMA传输模式:选择ADC1、ADC2、ADC1与ADC2、ADC1与ADC2轮流
7)ADC DMA传输转换格式:12BIT转换/11BIT转换
在这里插入图片描述
在这里插入图片描述

对于设置的输出格式来说如果设置输出12BIT的数据,那么输出的16位中存放格式是[15:12] 通道,[11:0]12 位 ADC 数据 。注意:对于单次转换模式。
如果设置的数是11BIT的数据那么存放内容就是[15]adc 单元,[14:11]通道,[10:0]11 位 ADC 数据 。注意:对于多或交替转换模式。

(7)检查 ADC 校准值是否烧入 eFuse

esp_err_t esp_adc_cal_check_efuse( esp_adc_cal_value_
### ESP32 NVS 学习教程 #### 非易失性存储(NVS)简介 非易失性存储(NVS)允许应用程序以键值对形式保存数据到闪存中,即使设备断电后也能保持这些数据不变。对于ESP32来说,这是一项非常有用的功能,可以用来储存配置参数或其他重要信息[^1]。 #### 初始化NVS分区 为了能够读取和写入NVS中的数据,在操作之前需要先初始化相应的分区: ```c #include "nvs_flash.h" void app_main(void){ // 初始化默认的NVS命名空间 esp_err_t err = nvs_flash_init(); if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { // 如果NVS尚未被初始化,则擦除并重新初始化 ESP_ERROR_CHECK(nvs_flash_erase()); err = nvs_flash_init(); } } ``` 这段代码展示了如何安全地初始化NVS分区,处理可能遇到的一些错误情况,比如当没有可用页面或者发现了新的版本时会执行擦除再重试的操作[^4]。 #### 向NVS中写入整数型数据 下面是一个简单的例子来展示怎样把一个`int32_t`类型的数值储存在指定的名字空间下,并赋予特定的关键字名称: ```c #include "nvs.h" #include "nvs_flash.h" static void write_data_to_nvs(const char *namespace_name, const char *key, int32_t value){ nvs_handle my_handle; esp_err_t err; // 打开给定名字的空间以便于写入 err = nvs_open(namespace_name, NVS_READWRITE, &my_handle); if (err != ESP_OK) return; // 将value作为名为key的数据项写入打开的手柄所指向的位置 err = nvs_set_i32(my_handle, key, value); // 提交更改至flash nvs_commit(my_handle); // 关闭当前使用的句柄 nvs_close(my_handle); } ``` 此函数接收三个参数:要访问的名字空间字符串、代表目标变量名的字符串以及待存储的实际数值。通过调用`nvs_open()`获取对应区域的一个手柄对象;接着利用该手柄配合`nvs_set_i32()`完成实际赋值工作;最后记得关闭这个连接以防资源泄露[^3]。 #### 从NVS中读取整数型数据 同样地,这里也给出了一段示范性的C语言程序片段用于提取先前已经存在的记录: ```c static bool read_data_from_nvs(const char *namespace_name, const char *key, int32_t *out_value){ nvs_handle my_handle; esp_err_t err; // 获取name_space对应的handle err = nvs_open(namespace_name, NVS_READONLY, &my_handle); if (err != ESP_OK) return false; // 查询是否存在key对应的值 err = nvs_get_i32(my_handle, key, out_value); // 不管成功与否都要释放掉handel nvs_close(my_handle); return err == ESP_OK ? true : false; } ``` 上述方法接受两个输入参数——所属的名字空间与查询关键字,还有一个指针形参用来返回找到的结果。如果一切顺利的话将会更新传入的指针位置处的内容为匹配上的那个整数值;反之则不会改变它原本的状态。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值