ESP32 您所在的位置:网站首页 c3代码 ESP32

ESP32

#ESP32| 来源: 网络整理| 查看: 265

经过前面的折腾,设计好了自己的测试开发板 搭建好了开发环境, 然后正式开始进行功能测试了,测试顺序先从简单的开始吧,一步一步来

目录 前言1、ADC采样示例测试1.1 DMA连续采样1.2 单次采样1.3 测试源码 2、 ESP32-C3 ADC相关介绍2.1 实际电压的计算2.2 连续采样步骤2.3 单步采样步骤2.4 ADC使用注意事项

前言

接下来的ESP32-C3 功能测试都是基于自己设计的开发板:

自己画一块ESP32-C3 的开发板(第一次使用立创EDA)(PCB到手)

开发环境是乐鑫官方的 ESP-IDF, 基于VScode插件搭建好的:

ESP32-C3 VScode开发环境搭建(基于乐鑫官方ESP-IDF——Windows和Ubuntu双环境)

1、ADC采样示例测试

新建一个ADC采样的工程,当然是基于官方的ADC示例代码建立的,建立工程的方式在上面开发环境搭建的示例测试章节有图文说明:

在这里插入图片描述

1.1 DMA连续采样

示例代码有2个函数,单次检测 和 DMA连续检测,分别接在如下通道上面:

在这里插入图片描述

在开发板上面,我们只预留了一个ADC接口,就是ADC1_CHANNEL_0,连接的是一个光敏电阻:

在这里插入图片描述

所以需要对示例进行稍微修改,主要是对读取函数,只设置 ADC1_CHANNEL_0 ,如下图:

在这里插入图片描述

在主函数中只调用continuous_read(NULL);函数,测试结果如下:

在这里插入图片描述

1.2 单次采样

单次采样比较简单,也是直接在上面的样例中修改,下面直接上修改后的测试代码:

static void single_read(void *arg) { // esp_err_t ret; // int adc1_reading[3] = {0xcc}; int adc1_reading[1] = {0xcc}; // int adc2_reading[1] = {0xcc}; float vout; // const char TAG_CH[][10] = {"ADC1_CH2", "ADC1_CH3","ADC1_CH4", "ADC2_CH0"}; const char TAG_CH[1][10] = {"ADC1_CH0"}; adc1_config_width(ADC_WIDTH_BIT_DEFAULT); adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_11); // adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_6); // adc1_config_channel_atten(ADC1_CHANNEL_4, ADC_ATTEN_DB_0); // adc2_config_channel_atten(ADC2_CHANNEL_0, ADC_ATTEN_DB_0); // int n = 20; // while (n--) { while (1) { adc1_reading[0] = adc1_get_raw(ADC1_CHANNEL_0); // adc1_reading[1] = adc1_get_raw(ADC1_CHANNEL_3); // adc1_reading[2] = adc1_get_raw(ADC1_CHANNEL_4); vout = (adc1_reading[0] * 2500.00)/4095.00; ESP_LOGI(TAG_CH[0], "%x vout mv is %f", adc1_reading[0],vout); // for (int i = 0; i < 3; i++) { // ESP_LOGI(TAG_CH[i], "%x", adc1_reading[i]); // } // ret = adc2_get_raw(ADC2_CHANNEL_0, ADC_WIDTH_BIT_12, &adc2_reading[0]); // assert(ret == ESP_OK); // ESP_LOGI(TAG_CH[3], "%x", adc2_reading[0]); vTaskDelay(500 / portTICK_PERIOD_MS); } } void app_main(void) { single_read(NULL); //continuous_read(NULL); }

测试效果如下:

在这里插入图片描述

1.3 测试源码

上一份自己稍微修改的最后测试的adc_dma_example_main.c源码

针对自己的板子只有一个 ADC 接口进行代码精简增加实际电压值的计算输出LED切换表示采样一次注释部分为了避免警告需要自行去掉,使用单次模式注释连续采样代码,反之一样 #include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" #include "esp_log.h" #include "driver/adc.h" #include "driver/gpio.h" #define TIMES 256 // static void continuous_adc_init(uint16_t adc1_chan_mask, uint16_t adc2_chan_mask, adc_channel_t *channel, uint8_t channel_num) // { // esp_err_t ret = ESP_OK; // assert(ret == ESP_OK); // adc_digi_init_config_t adc_dma_config = { // .max_store_buf_size = 1024, // .conv_num_each_intr = 256, // .adc1_chan_mask = adc1_chan_mask, // .adc2_chan_mask = adc2_chan_mask, // }; // ret = adc_digi_initialize(&adc_dma_config); // assert(ret == ESP_OK); // adc_digi_pattern_table_t adc_pattern[10] = {0}; // //Do not set the sampling frequency out of the range between `SOC_ADC_SAMPLE_FREQ_THRES_LOW` and `SOC_ADC_SAMPLE_FREQ_THRES_HIGH` // adc_digi_config_t dig_cfg = { // .conv_limit_en = 0, // .conv_limit_num = 250, // .sample_freq_hz = 620, // }; // dig_cfg.adc_pattern_len = channel_num; // for (int i = 0; i < channel_num; i++) { // uint8_t unit = ((channel[i] >> 3) & 0x1); // uint8_t ch = channel[i] & 0x7; // adc_pattern[i].atten = ADC_ATTEN_DB_11; // adc_pattern[i].channel = ch; // adc_pattern[i].unit = unit; // } // dig_cfg.adc_pattern = adc_pattern; // ret = adc_digi_controller_config(&dig_cfg); // assert(ret == ESP_OK); // } // 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; // } // static void continuous_read(void *arg) // { // esp_err_t ret; // uint32_t ret_num = 0; // uint8_t result[TIMES] = {0}; // memset(result, 0xcc, TIMES); // float vout; // // uint16_t adc1_chan_mask = BIT(0) | BIT(1); // uint16_t adc1_chan_mask = BIT(0); // uint16_t adc2_chan_mask = BIT(0); // // adc_channel_t channel[3] = {ADC1_CHANNEL_0, ADC1_CHANNEL_1, (ADC2_CHANNEL_0 | 1 // adc_digi_output_data_t *p = (void*)&result[i]; // if (check_valid_data(p)) { // vout = (p->type2.data * 2500.00)/4095.00; // printf("ADC%d_CH%d: %x voltage is %fmv\n", p->type2.unit+1, p->type2.channel, p->type2.data,vout); // } else { // printf("Invalid data [%d_%d_%x]\n", p->type2.unit+1, p->type2.channel, p->type2.data); // } // } // vTaskDelay(1000 / portTICK_PERIOD_MS); // // If you see task WDT in this task, it means the conversion is too fast for the task to handle // } // adc_digi_stop(); // ret = adc_digi_deinitialize(); // assert(ret == ESP_OK); // } static void single_read(void *arg) { // esp_err_t ret; // int adc1_reading[3] = {0xcc}; int adc1_reading[1] = {0xcc}; // int adc2_reading[1] = {0xcc}; uint32_t etc = 2; float vout; // const char TAG_CH[][10] = {"ADC1_CH2", "ADC1_CH3","ADC1_CH4", "ADC2_CH0"}; const char TAG_CH[1][10] = {"ADC1_CH0"}; gpio_set_direction(1, GPIO_MODE_OUTPUT); adc1_config_width(ADC_WIDTH_BIT_DEFAULT); adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_11); // adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_6); // adc1_config_channel_atten(ADC1_CHANNEL_4, ADC_ATTEN_DB_0); // adc2_config_channel_atten(ADC2_CHANNEL_0, ADC_ATTEN_DB_0); // int n = 20; // while (n--) { while (1) { adc1_reading[0] = adc1_get_raw(ADC1_CHANNEL_0); // adc1_reading[1] = adc1_get_raw(ADC1_CHANNEL_3); // adc1_reading[2] = adc1_get_raw(ADC1_CHANNEL_4); vout = (adc1_reading[0] * 2500.00)/4095.00; ESP_LOGI(TAG_CH[0], "%x vout mv is %f", adc1_reading[0],vout); // for (int i = 0; i < 3; i++) { // ESP_LOGI(TAG_CH[i], "%x", adc1_reading[i]); // } ret = adc2_get_raw(ADC2_CHANNEL_0, ADC_WIDTH_BIT_12, &adc2_reading[0]); // assert(ret == ESP_OK); // ESP_LOGI(TAG_CH[3], "%x", adc2_reading[0]); vTaskDelay(500 / portTICK_PERIOD_MS); etc++; if(etc%2){ gpio_set_level(1,1); } else gpio_set_level(1,0); if(etc > 60000) etc = 2; } } void app_main(void) { single_read(NULL); //continuous_read(NULL); } 2、 ESP32-C3 ADC相关介绍

对于ESP32-C3 ADC的介绍,在乐鑫的官网有很详细的说明,官方链接如下:

乐鑫官方ESP32-C3 ADC部分说明

2.1 实际电压的计算

对于实际电压的计算,有如下计算公式:

在这里插入图片描述 其中 Vmax 中的 ADC Attenuation 在官方文档中如下介绍:

在这里插入图片描述

在 SDK 的库函数中 使用枚举类型定义的,如下(数值上有一点区别):

在这里插入图片描述

在示例中根据公式测试电压值的计算:

在这里插入图片描述

在库函数中也有关于电压转换的函数esp_adc_cal_get_voltage,其中调用了esp_adc_cal_raw_to_voltage进行计算:

在这里插入图片描述 源码如下:

/* esp_adc_cal_characteristics_t 结构体如下 typedef struct { adc_unit_t adc_num; /**< ADC number adc_atten_t atten; /**< ADC attenuation adc_bits_width_t bit_width; /**< ADC bit width uint32_t coeff_a; /**< Gradient of ADC-Voltage curve uint32_t coeff_b; /**< Offset of ADC-Voltage curve uint32_t vref; /**< Vref used by lookup table const uint32_t *low_curve; /**< Pointer to low Vref curve of lookup table (NULL if unused) const uint32_t *high_curve; /**< Pointer to high Vref curve of lookup table (NULL if unused) } esp_adc_cal_characteristics_t; 计算函数如下: uint32_t esp_adc_cal_raw_to_voltage(uint32_t adc_reading, const esp_adc_cal_characteristics_t *chars) { ADC_CALIB_CHECK(chars != NULL, "No characteristic input.", ESP_ERR_INVALID_ARG); return adc_reading * chars->coeff_a / coeff_a_scaling + chars->coeff_b / coeff_b_scaling; } */ esp_err_t esp_adc_cal_get_voltage(adc_channel_t channel, const esp_adc_cal_characteristics_t *chars, uint32_t *voltage) { // Check parameters ADC_CALIB_CHECK(chars != NULL, "No characteristic input.", ESP_ERR_INVALID_ARG); ADC_CALIB_CHECK(voltage != NULL, "No output buffer.", ESP_ERR_INVALID_ARG); int adc_reading; if (chars->adc_num == ADC_UNIT_1) { //Check if channel is valid on ADC1 ADC_CALIB_CHECK((adc1_channel_t)channel return ESP_ERR_TIMEOUT; //Timed out waiting for ADC2 } } *voltage = esp_adc_cal_raw_to_voltage((uint32_t)adc_reading, chars); return ESP_OK; } 2.2 连续采样步骤

官方的连续采样步骤说明:

在这里插入图片描述 根据说明我们对比一下示例代码:

在这里插入图片描述

2.3 单步采样步骤

在这里插入图片描述 根据说明我们对比一下示例代码:

在这里插入图片描述

2.4 ADC使用注意事项

还是官方手册,简单说明一下:

ADC2模块也被 WI-FI 组件使用了,所以在 esp_err_t esp_wifi_start(void) 和esp_err_t esp_wifi_stop(void)函数之间进行 ADC2 读取,不一定能够获得正确的值,其实这点我们在使用中尽量避免就可以一个特定的ADC模块在同一时间只能工作在一种工作模式下(单次和连续模式)ADC1和ADC2不能同时在单读模式下工作。其中一个会被阻塞,直到另一个完成。对于连续(DMA)模式,ADC采样频率应该在SOC_ADC_SAMPLE_FREQ_THRES_LOW和SOC_ADC_SAMPLE_FREQ_THRES_HIGH范围内。 在这里插入图片描述


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有