打印
[家电应用]

ADC采集精度不良

[复制链接]
1738|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
灰色与青|  楼主 | 2025-7-9 18:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
空调控制板在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);
    }
}



使用特权

评论回复
沙发
powerantone| | 2025-7-11 16:56 | 只看该作者
参考电压不稳定?

使用特权

评论回复
板凳
flycamelaaa| | 2025-7-11 19:57 | 只看该作者
可能是模拟信号源阻抗过高。

使用特权

评论回复
地板
stormwind123| | 2025-7-11 20:57 | 只看该作者
ADC采样需要一定时间对输入信号充电,若采样时间过短,会导致采样值不准确。

使用特权

评论回复
5
probedog| | 2025-7-11 22:58 | 只看该作者
未进行多次采样平均,单次采样可能受噪声干扰,导致结果波动。

使用特权

评论回复
6
治愈糖果屋| | 2025-7-12 14:08 | 只看该作者
看来问题出在校准参数上,重新校准后温度采集数据更准确了。这个案例提醒我们,硬件调试时不仅要检查硬件连接,还要关注软件参数设置。

使用特权

评论回复
7
时光贩卖机| | 2025-7-17 22:13 | 只看该作者
看起来问题出在AD转换的校准参数上,重新校准后问题解决了,这个方法很实用,感谢分享经验!

使用特权

评论回复
8
星辰大海不退缩| | 2025-7-28 12:43 | 只看该作者
使用万用表测量温度传感器的输出信号是一种检测手段

使用特权

评论回复
9
暖心小太阳| | 2025-7-29 17:53 | 只看该作者
看来问题出在校准参数上,重新校准后效果如何?能否分享下校准后的温度采集数据?

使用特权

评论回复
10
治愈糖果屋| | 2025-7-30 11:36 | 只看该作者
看来问题出在校准参数上,重新校准后效果如何?是否已经解决了温度控制不准确的问题?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

9

主题

31

帖子

0

粉丝