问答

汇集网友智慧,解决技术难题

21ic问答首页 -

AD ADC adc采集 dc 精度

2025-08-26
空调控制板在demo调试的时候,温度控制不准确。尽管检查温度传感器的连接,确保传感器与 MCU 的连接正常,无松动或断路情况。使用万用表测量温度传感器的输出信号,信号正常。
查看 MCU 的温度采集程序,发现 AD 转换的校准参数未正确设置,导致采集到的温度数据与实际温度存在偏差。根据温度传感器的特性曲线,重新校准了 AD 转换参数后,温度采集数据更加准确
#include "shinelon.h"  //

// 温度传感器相关参数
#define TEMP_SENSOR_ADC_CHANNEL  0x03  // 温度传感器连接的ADC通道
#define REFERENCE_VOLTAGE        3.3f  // 参考电压(V)
#define ADC_RESOLUTION           4096  // ADC分辨率(12位)
#define TEMP_SENSOR_BETA         3950  // NTC热敏电阻B值
#define TEMP_SENSOR_R25          10000 // NTC热敏电阻25℃时的阻值(Ω)
#define SERIES_RESISTOR          10000 // 分压电阻阻值(Ω)
#define ROOM_TEMP_KELVIN         298.15f // 室温(25℃)对应的开尔文温度

// ADC初始化函数
void ADC_Init(void)
{
    // 使能ADC时钟
    CLK->PERI_CLK |= (1 << ADC_CLK_EN);

    // 配置ADC采样时间
    ADC->SAMPLE_TIME = 0x1F;  // 设置最大采样时间

    // 配置ADC参考电压为VDD
    ADC->REF_SEL = 0;

    // 使能ADC
    ADC->CTRL |= (1 << ADC_EN);

    // 等待ADC稳定
    delay_ms(1);
}

// 读取ADC值
uint16_t ADC_Read(uint8_t channel)
{
    uint16_t adc_value = 0;

    // 选择ADC通道
    ADC->CHANNEL = channel;

    // 启动ADC转换
    ADC->CTRL |= (1 << ADC_START);

    // 等待转换完成
    while(!(ADC->STATUS & (1 << ADC_DONE)));

    // 清除转换完成标志
    ADC->STATUS |= (1 << ADC_DONE);

    // 读取ADC值
    adc_value = ADC->DATA;

    return adc_value;
}

// 将ADC值转换为温度(摄氏度)
float Convert_ADC_To_Temperature(uint16_t adc_value)
{
    float voltage, resistance, temperature;

    // 将ADC值转换为电压
    voltage = (float)adc_value * REFERENCE_VOLTAGE / ADC_RESOLUTION;

    // 计算NTC热敏电阻阻值
    // 分压公式: Vout = Vin * Rntc / (Rntc + Rseries)
    // 变形: Rntc = Rseries * Vout / (Vin - Vout)
    resistance = SERIES_RESISTOR * voltage / (REFERENCE_VOLTAGE - voltage);

    // 使用B值方程计算温度(开尔文)
    // 1/T = 1/T0 + (1/B) * ln(R/R0)
    temperature = 1.0f / ((1.0f / ROOM_TEMP_KELVIN) +
                (1.0f / TEMP_SENSOR_BETA) * log(resistance / TEMP_SENSOR_R25));

    // 转换为摄氏度
    temperature -= 273.15f;

    return temperature;
}

// 主函数
int main(void)
{
    uint16_t adc_value;
    float temperature;

    // 系统初始化
    SystemInit();

    // 初始化ADC
    ADC_Init();

    while(1)
    {
        // 读取温度传感器ADC值
        adc_value = ADC_Read(TEMP_SENSOR_ADC_CHANNEL);

        // 转换为温度值
        temperature = Convert_ADC_To_Temperature(adc_value);

        // 这里可以添加显示或处理温度值的代码
        // 例如通过串口输出温度值
        // UART_SendString("Temperature: ");
        // UART_SendFloat(temperature);
        // UART_SendString(" C\r\n");

        // 延时一段时间
        delay_ms(1000);
    }
}



回答 +关注
人浏览 人回答问题 分享 举报
个回答

您需要登录后才可以回复 登录 | 注册