[接口]ESP32-C3的ADC


//----------------------ADC任务开始------------------------------------------
#include "driver/adc.h"
#include "esp_adc_cal.h"
#include "driver/gpio.h"

#define DEFAULT_VREF    3300 // 使用 adc2_vref_to_gpio() 来获取更准确的估计值
#define NO_OF_SAMPLES   64    // 多次采样以平滑数据

// 静态变量保存 ADC 校准的特征值
static esp_adc_cal_characteristics_t *adc_chars;

/*
* @brief  初始化 ADC 通道以及校准特性。
*         该函数将配置所选的 ADC 单元和通道,以及它们的读取分辨率和衰减。
*
* @param  unit   ADC 单元,例如 ADC_UNIT_1 或 ADC_UNIT_2(取决于 ESP32 的具体型号)。
* @param  channel 要初始化的 ADC 通道,如 ADC1_CHANNEL_0、ADC1_CHANNEL_1 等。
* @param  width   采样时的位宽,例如 ADC_WIDTH_BIT_12 表示12位分辨率。
* @param  atten   输入衰减,控制输入电压范围,例如 ADC_ATTEN_DB_11 用于增加最大可检测电压。
  adc_init(ADC_UNIT_1, ADC1_CHANNEL_0, ADC_WIDTH_BIT_12, ADC_ATTEN_DB_11);
*/
void adc_init(adc_unit_t unit, adc_channel_t channel, adc_bits_width_t width, adc_atten_t atten)
{

    // 检查 eFuse 中是否烧录了 Two Point 或 Vref
    adc1_config_width(width);
    adc1_config_channel_atten(channel, atten);

    // 为 ADC 分配校准特性结构体空间
    if (adc_chars == NULL)
    {
        adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t));
        if (adc_chars == NULL)
        {
            printf("calloc----->ESP_FAIL\n"); // 处理内存分配失败情况
        }
    }

    // 初始化 ADC 校准特性
    esp_adc_cal_characterize(unit, atten, width, DEFAULT_VREF, adc_chars);
}

// 读取指定 ADC 通道的 ADC 值
uint32_t adc_read(adc_channel_t channel)
{
    uint32_t adc_reading = 0;
    // 进行多次采样以平滑结果
    for (int i = 0; i < NO_OF_SAMPLES; i++)
    {
        adc_reading += adc1_get_raw(channel);
    }
    adc_reading /= NO_OF_SAMPLES;

    // 将 adc_reading 转换为毫伏 (mV)
    uint32_t millivolts = esp_adc_cal_raw_to_voltage(adc_reading, adc_chars);
    return millivolts;
}


static void ADC_task(void *pvParameters)
{
    uint32_t last_voltage = 0; // 保存上一次读取的电压值
    uint32_t voltage = 0;      // 当前读取的电压值

    adc_init(ADC_UNIT_1, ADC1_CHANNEL_1, ADC_WIDTH_BIT_12, ADC_ATTEN_DB_11);

    while (1)
    {
        voltage = adc_read(ADC1_CHANNEL_1); // 读取当前电压值

        if (voltage != last_voltage)   // 如果电压值与上一次不同
        {
        	printf("Voltage: %lu mV\n", (unsigned long)voltage); // 打印电压值
            last_voltage = voltage; // 更新上一次读取的电压值
        }

        //esp_task_wdt_reset(); // 喂狗
        vTaskDelay(20 / portTICK_PERIOD_MS); //20ms
    }
}

//----------------------ADC任务结束--------------------------------------------

void app_main(void)
{

    /*
    // 看门狗
    esp_task_wdt_config_t wdt_config =
    {
        .timeout_ms = 30000,         // 看门狗定时器超时时间(以毫秒为单位)
        .idle_core_mask = 0x0,       // 不订阅空闲任务
        .trigger_panic = false       // 超时不触发 panic
    };

    // 初始化任务看门狗
    esp_err_t err = esp_task_wdt_init(&wdt_config);
    if (err != ESP_OK)
    {
        printf("wdt----->ESP_FAIL\n");
    }
    */

    esp_log_level_set(TAG, ESP_LOG_VERBOSE);
    // 配置定时器超时时间(以毫秒为单位)


    //xTaskCreate(&LED_task, "LED_task", 2048, NULL, 5, NULL); // 创建显示任务
    xTaskCreate(&ADC_task, "ADC_task", 2048, NULL, 3, NULL); // 创建ADC任务
    xTaskCreate(&PWM_LED_task, "PWM_LED_task", 2048, NULL, 4, NULL); // 创建显示任务
    xTaskCreate(&Btn_task, "Btn_task", 2048, NULL, 5, NULL); // 创建按键任务

    while (1)
    {
        // 喂狗
        //esp_task_wdt_reset();
        vTaskDelay(10000 / portTICK_PERIOD_MS); //10000ms
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值