ADC Continuous Read 示例
示例说明
本示例展示如何初始化和配置 ADC 以及如何使用 ADC 连续采样模式采集模拟输入信号并进行处理。有关 ADC 连续转换模式的说明可参考 模数转换器 (ADC) 连续转换模式驱动。学习该示例前,建议先掌握 FreeRTOS 信号量的相关内容,其基础说明及 API 使用示例可参考 信号量和互斥锁 文档。
运行方法
示例完整代码见 ADC Continuous Read 示例。运行前的配置说明、构建与烧录流程详见 adc
目录下的 README.md 文件。
如需自定义配置项及查看默认值,可参考 全局变量/宏定义说明 部分。
头文件说明
本示例所使用的头文件涵盖了 FreeRTOS 任务管理与同步机制、常用系统工具以及 ADC 连续采样驱动等基础模块。为任务创建、ADC 初始化、采集及处理提供支持。
各头文件按功能分类如下:
FreeRTOS 任务调度 :提供任务创建、调度和管理功能,并支持任务同步机制,确保多任务环境下的资源共享和通信。
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
系统工具 :提供系统配置文件,以及输入输出、字符串处理、日志记录功能,用于程序的调试、配置和运行管理。
#include <string.h>
#include <stdio.h>
#include "sdkconfig.h"
#include "esp_log.h"
ADC 驱动 :提供 ADC 连续采样模式初始化、通道配置、原始数据读取及采集结果处理功能。
#include "esp_adc/adc_continuous.h"
全局变量/宏定义说明
本示例中涉及的宏定义主要用于定义 GPIO 输入输出引脚以及中断标志位。
宏定义按功能分类如下:
ADC 单元选择
定义所使用的 ADC 单元。本示例使用
ADC_UNIT_1
,即 ADC1 外设。#define EXAMPLE_ADC_UNIT ADC_UNIT_1
将 ADC 单元宏转换为字符串形式,用于日志或调试输出。
#define _EXAMPLE_ADC_UNIT_STR(unit) #unit #define EXAMPLE_ADC_UNIT_STR(unit) _EXAMPLE_ADC_UNIT_STR(unit)
ADC 参数设置
设置 ADC 转换模式,指定使用单 ADC 单元采样。
#define EXAMPLE_ADC_CONV_MODE ADC_CONV_SINGLE_UNIT_1
设置 ADC 通道的衰减为 0 dB。
#define EXAMPLE_ADC_ATTEN ADC_ATTEN_DB_0
设置 ADC 采样位宽,通常使用芯片支持的最大位宽
SOC_ADC_DIGI_MAX_BITWIDTH
。#define EXAMPLE_ADC_BIT_WIDTH SOC_ADC_DIGI_MAX_BITWIDTH
ADC 输出数据格式与访问:根据芯片型号(是否是 ESP32 芯片或 ESP32-S2 芯片)选择不同的数据输出格式与访问路径。
定义 ADC 数字输出数据格式,针对不同芯片选择
TYPE1
或TYPE2
。根据芯片类型定义如何从 ADC 输出数据结构中获取通道号。
根据芯片类型定义如何从 ADC 输出数据结构中获取原始采样数据。
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 #define EXAMPLE_ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE1 // 输出数据格式 #define EXAMPLE_ADC_GET_CHANNEL(p_data) ((p_data)->type1.channel) // 获取通道号 #define EXAMPLE_ADC_GET_DATA(p_data) ((p_data)->type1.data) // 获取原始采样数据 #else #define EXAMPLE_ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE2 // 输出数据格式 #define EXAMPLE_ADC_GET_CHANNEL(p_data) ((p_data)->type2.channel) // 获取通道号 #define EXAMPLE_ADC_GET_DATA(p_data) ((p_data)->type2.data) // 获取原始采样数据 #endif
数据采集长度:定义每次数据采集的读取长度为 256,用于分配缓冲区的大小。
#define EXAMPLE_READ_LEN 256
定义全局变量:
根据芯片型号定义 ADC 通道数组
channel[]
:
当目标芯片为 ESP32 时,选择
ADC_CHANNEL_6
与ADC_CHANNEL_7
。当目标芯片为其他芯片时,选择
ADC_CHANNEL_2
与ADC_CHANNEL_3
。定义 FreeRTOS 任务句柄变量
s_task_handle
,用于在 FreeRTOS 环境下管理或控制任务。
任务函数说明
本示例中,为了实现 ADC 连续采样模式的初始化,并成功完成采样及数据处理,提供了两个相关任务函数:ADC 初始化函数和连续采样完成回调函数。
ADC 初始化函数
continuous_adc_init()
为 ADC 初始化函数,用于初始化 ADC 连续采样模式并完成通道配置,使得后续的数据采集和处理能够顺利进行。
传入参数 |
参数功能 |
参数说明 |
---|---|---|
|
指向 ADC 通道数组的指针 |
用于指定需要进行连续采样的通道列表。每个元素表示一个 ADC 通道编号。 |
|
通道数组中通道的数量 |
用于配置 ADC 连续采样时实际使用的通道数。 |
|
ADC 模块句柄 |
输出参数,返回初始化完成的 ADC 连续采样模块句柄,用于后续启动采样、读取数据或注销模块时进行操作。 |
该函数的执行逻辑为:
ADC 通道模式数组长度为
SOC_ADC_PATT_LEN_MAX
,为 ADC 数字控制器模式下支持的最大通道配置数量。遍历配置每个通道并打印配置日志,便于调试和验证。
将函数内生成的 ADC 采样模块句柄保存到传参
out_handle
。
连续采样完成回调函数
s_conv_done_cb()
是一个回调函数,主要用于处理 ADC 连续采样模式下的采样完成事件。它在每次 ADC 连续采样完成预定数量的转换后被触发。
传入参数 |
参数功能 |
参数说明 |
---|---|---|
|
已创建的 ADC 连续采样模块的句柄 |
用于访问与当前 ADC 连续采样相关的配置和状态,便于进行进一步操作或管理采样任务。 |
|
指向 ADC 连续采样事件的数据结构 |
用于访问采样数据,从而进行数据处理或其他相关操作。 |
|
用户自定义的数据 |
用于标识任务句柄或进行任务通知。 |
该函数的执行逻辑为:
定义标志变量
mustYield
,用于指示在回调执行后是否需要立即切换任务,初始化为pdFALSE
。调用
vTaskNotifyGiveFromISR()
向指定任务发送通知,告知 ADC 连续采样已完成规定数量的转换。判断
mustYield
是否为pdTRUE
,并将其返回给调度器,以便在必要时切换到高优先级任务执行。
主函数说明
本函数展示了 ADC 连续采样模式的完整流程,包括初始化 ADC 单元、配置采样通道、注册采样完成回调、执行软件校准,以及循环读取和处理采样数据。
定义变量:
创建返回值变量
ret
用于错误检查和日志输出,确保调用者能根据不同返回值采取不同处理。创建变量
ret_num
并初始化为 0,用于记录每次读取到的数据长度(字节数)。创建数组
result[]
并初始化为0xcc
,用于存储 ADC 连续采样返回的原始数据。数组长度为自定义宏EXAMPLE_READ_LEN
。
调用
xTaskGetCurrentTaskHandle()
获取当前任务句柄,供回调函数中通知任务使用。进一步说明及使用示例可参考 任务信息 API。初始化 ADC 连续采样模块:
创建 ADC 连续采样模块句柄
handle
并初始化为NULL
,用于后续操作 ADC 模块。调用
continuous_adc_init()
,根据指定的 ADC 通道数组创建并配置 ADC 连续采样模块,并保存返回的句柄至handle
。
备注
事件回调函数常用于处理采样结果并进行后续操作,但不是 ADC 联系采样模块中的必备步骤。
如果选择使用回调函数,可以在每次采样完成后由回调函数自动处理数据,适合需要实时处理或数据处理频繁的场景。回调函数可以有效避免轮询等待,提高系统响应效率。
如果不使用回调函数,可以选择通过轮询的方式检测采样是否完成,然后手动处理采样数据。这种方式可能适用于不需要立即处理数据或控制逻辑较简单的场景。
备注
步骤 6、7 在数据处理循环中执行。
调用
ulTaskNotifyTake()
阻塞等待回调通知,确保在采样完成后处理数据。循环读取数据:
循环调用
adc_continuous_read()
读取 ADC 缓冲区数据,直到缓冲区中没有可用数据(返回ESP_ERR_TIMEOUT
)。进一步介绍及参数说明可参考 ADC 驱动。将读取到的原始数据解析为
adc_digi_output_data_t
结构体,并通过宏EXAMPLE_ADC_GET_CHANNEL
和EXAMPLE_ADC_GET_DATA
获取通道号和采样值。具体结构体成员可参考 ADC 驱动。检查每条数据的有效性,确保通道号未超出最大通道数,并通过日志打印通道号和采样值。
为防止任务看门狗超时,在每次循环末尾调用
vTaskDelay(1)
暂停 1 个 tick。
任务结束后停止与释放 ADC 模块。
备注
在实际应用中,连续采样任务通常为长期运行或常驻任务,因此该步骤一般不被执行,但可以用于防止潜在的程序异常或内存泄漏。