单片机/MCU论坛
直播中

王栋春

12年用户 44363经验值
擅长:电源/新能源
私信 关注
[讨论]

ADC采集精度不良

空调控制板在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);
}

}

更多回帖

发帖
×
20
完善资料,
赚取积分