一、概述
1.1 ADC通道
ESP32 集成了 2 个 12 位逐次逼近模数转换器 (SARADC),支持 18 个测量通道(模拟使能引脚)。
支持以下通道:
ADC1:
- 8个通道:GPIO32 - GPIO39
ADC2: - 10个通道:GPIO0、GPIO2、GPIO4、GPIO12-GPIO15、GOIO25-GPIO27
1.2 ADC的限制
由于WiFi模块驱动使用了ADC2,所以只能只能在WiFi模块未使用的情况下才能使用ADC2
1.3 ADC的采样模式
每一个ADC都支持两个采样模式:ADC单次采样模式和ADC连续采样(DMA)模式。
ADC单次采样模式适用于低频采样
ADC连续采样(DMA)模式适用于高频连续采样
1.4 ADC的衰减
如果对于ESP32单片机的采集电压过大,而ADC的衰减也不是合适的值,ADC将对电压采集无效,而通过更高设置的电压衰减越高,能读取的电压值就越高,与电压相对于的衰减如下:
衰减 | 可测量的输入电压范围 |
---|---|
ADC_ATTEN_DB_0 | 100毫伏 ~ 950毫伏 |
ADC_ATTEN_DB_2_5 | 100 毫伏 ~ 1250 毫伏 |
ADC_ATTEN_DB_6 | 150 毫伏 ~ 1750 毫伏 |
ADC_ATTEN_DB_11 | 150 毫伏 ~ 2450 毫伏 |
1.5 ADC的噪音最小化
由于ADC转换的实质原理是将模拟信号转变为数字信号,而模拟信号在传输的过程中难免会被外界因素干扰,克服这一因素的方法可以在输入电路上并连一个电容,可以最大限度的降低噪音。
1.6 GPIO查找
在源码中,一般会从通道告诉我们ADC1或者ADC2的GPIO为多少,改变ADC的通道即可改变相对应的GPIO
二、API参考
ADC的配置大致有:
设置衰减、捕获位宽、初始化数字ADC、通过DMA从数字ADC读取字节,还要获取ADC处理转换后的预期长度、限制转换时间和触发次数的上限等一系列的配置,现在我们从代码中来获取详细信息:
adc_digi_configuration_t dig_cfg = {
.conv_limit_en = ADC_CONV_LIMIT_EN, //限制ADC的转换时间
.conv_limit_num = 250, //设置ADC转换触发次数的上限
.sample_freq_hz = 10*1000, //以赫兹为单位的预期ADC采样频率
.conv_mode = ADC_CONV_MODE, //仅使用ADC1进行转换
.format = ADC_OUTPUT_TYPE, //输出类型
};
限制ADC的转换时间是为了防止在转换时已经进入超时了还在傻傻的等,能及时跳出并打印信息;
设置ADC转换触发次数的上限是为了限制预处理长度的值;
其他的为字面意思;
static void continuous_adc_init(uint16_t adc1_chan_mask, uint16_t adc2_chan_mask, adc_channel_t *channel, uint8_t channel_num)
{
adc_digi_init_config_t adc_dma_config = {
.max_store_buf_size = 256, //驱动程序在处理转换后的数据之前可以存储的最大长度
.conv_num_each_intr = 128, // ADC读取的预期数据长度
.adc1_chan_mask = adc1_chan_mask, //初始化ADC1的通道列表
.adc2_chan_mask = adc2_chan_mask, //初始化ADC2的通道列表
};
其中 .max_store_buf_size 为最大存储长度;
.conv_num_each_intr = 128 为一次从DMA中读出来的长度;
其他的即为标识的意思
adc_digi_pattern_config_t adc_pattern[SOC_ADC_PATT_LEN_MAX] = {0};
//将使用的ADC通道数量
dig_cfg.pattern_num = channel_num;
for (int i = 0; i < channel_num; i++)
{
uint8_t unit = GET_UNIT(channel[i]);
uint8_t ch = channel[i] & 0x7;
adc_pattern[i].atten = ADC_ATTEN_DB_11; //该ADC的通道衰减
adc_pattern[i].channel = ch; // ADC的通道
adc_pattern[i].unit = unit; // ADC的单元
adc_pattern[i].bit_width = SOC_ADC_DIGI_MAX_BITWIDTH; // ADC的输出宽度
}
这里配置ADC的衰减、通道、输出单元和输出宽度,目的是DMA从ADC按钮中获取每一个按键的电压值,并存入相对应的缓冲区。
adc_digi_read_bytes(result, TIMES, &ret_num, 3000 );
这里为从DMA读取值,然后进行输出,其中参数的意思为:
ADC读取的缓冲区、ADC读取的预期数据长度、ADC读取的实际长度、等待时间;
三、总结
本次学习主要参考官方例程dma_read,该例程可以说功能是很强大的,从理论上来说可以通过ADC的GPIO端口控制无数个按钮进行连续输出,而且每个按钮都是独立存在的,可以分别工作在不同的场合,例如配合DAC输出不同的波形,还可以控制波形的振幅、频率、相位等,只要想法大胆,还可以实现更多的功能,也可以在后续做出不同的项目。