//----------------------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
}
}
[接口]ESP32-C3的ADC
最新推荐文章于 2024-07-12 16:23:11 发布