灰色与青 发表于 2025-7-9 18:39

ADC采集精度不良

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

// 温度传感器相关参数
#define TEMP_SENSOR_ADC_CHANNEL0x03// 温度传感器连接的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);
    }
}



powerantone 发表于 2025-7-11 16:56

参考电压不稳定?

flycamelaaa 发表于 2025-7-11 19:57

可能是模拟信号源阻抗过高。

stormwind123 发表于 2025-7-11 20:57

ADC采样需要一定时间对输入信号充电,若采样时间过短,会导致采样值不准确。

probedog 发表于 2025-7-11 22:58

未进行多次采样平均,单次采样可能受噪声干扰,导致结果波动。

治愈糖果屋 发表于 2025-7-12 14:08

看来问题出在校准参数上,重新校准后温度采集数据更准确了。这个案例提醒我们,硬件调试时不仅要检查硬件连接,还要关注软件参数设置。
页: [1]
查看完整版本: ADC采集精度不良