1. 问题的引出
read_raw = adc1_get_raw(ADC1_TEST_CHANNEL)
2. 踩坑
3. 源码
#include <string.h>
#include <stdio.h>
#include "sdkconfig.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "driver/adc.h"
#define TIMES 256
#define GET_UNIT(x) ((x >> 3) & 0x1)
static volatile int16_t adc1_channel_5_value;
static volatile int16_t adc1_channel_7_value;
#define ADC_RESULT_BYTE 2
#define ADC_CONV_LIMIT_EN 1
#define ADC_CONV_MODE ADC_CONV_SINGLE_UNIT_1
#define ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE1
static uint16_t adc1_chan_mask = BIT(5) | BIT(7);
static uint16_t adc2_chan_mask = 0;
static adc_channel_t channel[2] = {ADC1_CHANNEL_5, ADC1_CHANNEL_7};
static const char *TAG = "ADC DMA";
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 = 1024,
.conv_num_each_intr = TIMES,
.adc1_chan_mask = adc1_chan_mask,
.adc2_chan_mask = adc2_chan_mask,
};
ESP_ERROR_CHECK(adc_digi_initialize(&adc_dma_config));
adc_digi_configuration_t dig_cfg = {
.conv_limit_en = ADC_CONV_LIMIT_EN,
.conv_limit_num = 250,
.sample_freq_hz = 20 * 1000,
.conv_mode = ADC_CONV_MODE,
.format = ADC_OUTPUT_TYPE,
};
adc_digi_pattern_config_t adc_pattern[SOC_ADC_PATT_LEN_MAX] = {0};
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_pattern[i].channel = ch;
adc_pattern[i].unit = unit;
adc_pattern[i].bit_width = SOC_ADC_DIGI_MAX_BITWIDTH;
ESP_LOGI(TAG, "adc_pattern[%d].atten is :%x", i, adc_pattern[i].atten);
ESP_LOGI(TAG, "adc_pattern[%d].channel is :%x", i, adc_pattern[i].channel);
ESP_LOGI(TAG, "adc_pattern[%d].unit is :%x", i, adc_pattern[i].unit);
}
dig_cfg.adc_pattern = adc_pattern;
ESP_ERROR_CHECK(adc_digi_controller_configure(&dig_cfg));
}
static bool check_valid_data(const adc_digi_output_data_t *data)
{
const unsigned int unit = data->type2.unit;
if (unit > 2)
return false;
if (data->type2.channel >= SOC_ADC_CHANNEL_NUM(unit))
return false;
return true;
}
void LOGTASK(void *param)
{
while (1)
{
vTaskDelay(1000 / portTICK_PERIOD_MS);
ESP_LOGI(TAG, "adc1_channel_5_value: %d,adc1_channel_7_value: %d", adc1_channel_5_value, adc1_channel_7_value);
}
}
void app_main(void)
{
esp_err_t ret;
uint32_t ret_num = 0;
uint8_t result[TIMES] = {0};
memset(result, 0xcc, TIMES);
xTaskCreate(LOGTASK, "LOGTASK", 5 * 1024, NULL, 2, NULL);
continuous_adc_init(adc1_chan_mask, adc2_chan_mask, channel, sizeof(channel) / sizeof(adc_channel_t));
adc_digi_start();
while (1)
{
ret = adc_digi_read_bytes(result, TIMES, &ret_num, ADC_MAX_DELAY);
if (ret == ESP_OK || ret == ESP_ERR_INVALID_STATE)
{
if (ret == ESP_ERR_INVALID_STATE)
{
}
for (int i = 0; i < ret_num; i += ADC_RESULT_BYTE)
{
adc_digi_output_data_t *p = (void *)&result[i];
{
if (p->type1.channel == ADC1_CHANNEL_5 || p->type1.channel == ADC1_CHANNEL_7)
{
switch (p->type1.channel)
{
case ADC1_CHANNEL_5:
adc1_channel_5_value = p->type1.data;
break;
case ADC1_CHANNEL_7:
adc1_channel_7_value = p->type1.data;
break;
default:
break;
}
}
}
vTaskDelay(1);
}
if (ret == ESP_ERR_TIMEOUT)
{
ESP_LOGW(TAG, "No data, increase timeout or reduce conv_num_each_intr");
vTaskDelay(1000);
}
}
}
adc_digi_stop();
ret = adc_digi_deinitialize();
assert(ret == ESP_OK);
}