基于NTC数据生成温度表格的实践

1、NTC热敏电阻介绍

        NTC热敏电阻是以Negative Temperature Coefficient的首字母缩写命名的热敏电阻。通常,“热敏电阻”一词指代的就是NTC热敏电阻。1833年,当时正在研究硫化银半导体的迈克尔·法拉第将其发现,塞缪尔·鲁本于20世纪30年代实现其商业化。NTC热敏电阻是一种由锰(Mn)、镍(Ni)和钴(Co)组成的氧化物半导体陶瓷。

        NTC在我们的生活中随处可见。由于阻值随温度的升高而降低的特性,它不仅被用作温度计、空调中的温度感应装置,抑或是智能手机、热水壶及熨斗中的温度控制装置,还被用于电源设备中的电流控制。最近,随着车辆电动化程度的提高,热敏电阻也越来越多地被用于车载产品。

1. 基本特性
  • 温度敏感性:电阻值随温度升高而非线性下降(典型下降曲线如图1所示)

典型参数范围

参数常用范围示例型号
标称电阻(R25)1kΩ~100kΩ10kΩ±1%
B值2000K~5000KB25/50=3950K
工作温度-40℃~125℃(工业级)MF52AT型
2. 关键特性曲线

电阻-温度曲线

  • 特征:指数衰减形态,低温区灵敏度更高

  • B值越大,曲线越陡峭,低温区分辨率越高

3. 动态特性
  • 热时间常数(τ)
    • 定义:温度变化至63.2%最终值所需时间

    • 典型值:3~60秒(与封装尺寸相关)

      封装类型典型τ值
      0402<5s
      环氧封装20-30s
  • 自热效应
    • 功率耗散公式:P=I2R

    • 安全操作区:通常限制电流<100μA(避免自热影响精度)

4、注意事项
  • 封装影响

    • 玻璃封装:响应快(τ<5s),但易碎

    • 环氧树脂:机械强度高,但τ较大(>20s)

  • 噪声抑制技巧

    • 并联100nF电容可降低高频噪声

    • 使用比率式测量(ADC基准与供电电压相同)

        使用建议:

  1. 优先选择B25/85值规格的型号

  2. 在目标温度范围中心点附近获得最高灵敏度

  3. 采用硬件滤波+软件补偿的组合方案

2、NTC数据手册概要

MF52 系列测温型 NTC 热敏电阻器
 

3、生成温度表格的步骤

1、选择上拉电阻,通常与NTC标称值相同

2、分压计算,计算NTC上的电压值

3、计算ADC的量化结果

4、以上用excel表格实现,结果如下图:

5、根据温度和ADC的量化结果的对应关系,逆推出ADC的量化结果与温度的函数,进而求得查表的表格,以matlab脚本实现

最佳拟合公式:
Temperature = 6.4938e-21*ADC^8 - 4.3075e-17*ADC^7 + 1.0562e-13*ADC^6 - 1.3181e-10*ADC^5 + 9.3314e-08*ADC^4 - 3.8838e-05*ADC^3 + 9.4897e-03*ADC^2 - 1.4088e+00*ADC + 1.6019e+02

// 温度值 = 存储值 - 55(统一偏移量)
const uint8_t ADC_TO_TEMP[1024] = {
   180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
   180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
   179,178,177,176,175,174,173,173,172,171,170,169,169,168,167,166,
   166,165,164,163,163,162,161,161,160,159,159,158,158,157,156,156,
   155,155,154,153,153,152,152,151,151,150,150,149,149,148,148,147,
   147,146,146,145,145,144,144,144,143,143,142,142,142,141,141,140,
   140,140,139,139,138,138,138,137,137,137,136,136,136,135,135,135,
   134,134,134,134,133,133,133,132,132,132,131,131,131,131,130,130,
   130,130,129,129,129,129,128,128,128,128,127,127,127,127,126,126,
   126,126,126,125,125,125,125,124,124,124,124,124,123,123,123,123,
   123,122,122,122,122,122,121,121,121,121,121,121,120,120,120,120,
   120,119,119,119,119,119,119,118,118,118,118,118,118,117,117,117,
   117,117,117,116,116,116,116,116,116,116,115,115,115,115,115,115,
   114,114,114,114,114,114,114,113,113,113,113,113,113,112,112,112,
   112,112,112,112,111,111,111,111,111,111,111,110,110,110,110,110,
   110,110,109,109,109,109,109,109,109,108,108,108,108,108,108,108,
   107,107,107,107,107,107,107,107,106,106,106,106,106,106,106,105,
   105,105,105,105,105,105,104,104,104,104,104,104,104,104,103,103,
   103,103,103,103,103,102,102,102,102,102,102,102,102,101,101,101,
   101,101,101,101,101,100,100,100,100,100,100,100,100, 99, 99, 99,
    99, 99, 99, 99, 99, 98, 98, 98, 98, 98, 98, 98, 98, 97, 97, 97,
    97, 97, 97, 97, 97, 96, 96, 96, 96, 96, 96, 96, 96, 95, 95, 95,
    95, 95, 95, 95, 95, 95, 94, 94, 94, 94, 94, 94, 94, 94, 94, 93,
    93, 93, 93, 93, 93, 93, 93, 93, 92, 92, 92, 92, 92, 92, 92, 92,
    92, 91, 91, 91, 91, 91, 91, 91, 91, 91, 90, 90, 90, 90, 90, 90,
    90, 90, 90, 90, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 88, 88,
    88, 88, 88, 88, 88, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, 87,
    87, 87, 87, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 85, 85,
    85, 85, 85, 85, 85, 85, 85, 85, 85, 84, 84, 84, 84, 84, 84, 84,
    84, 84, 84, 84, 84, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
    83, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 81, 81, 81,
    81, 81, 81, 81, 81, 81, 81, 81, 81, 80, 80, 80, 80, 80, 80, 80,
    80, 80, 80, 80, 80, 80, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
    79, 79, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 77,
    77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 76, 76, 76, 76, 76,
    76, 76, 76, 76, 76, 76, 76, 75, 75, 75, 75, 75, 75, 75, 75, 75,
    75, 75, 75, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 73,
    73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 72, 72, 72, 72, 72,
    72, 72, 72, 72, 72, 72, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
    71, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 69, 69, 69, 69,
    69, 69, 69, 69, 69, 69, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
    68, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 66, 66, 66, 66, 66,
    66, 66, 66, 66, 66, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 64,
    64, 64, 64, 64, 64, 64, 64, 64, 63, 63, 63, 63, 63, 63, 63, 63,
    63, 63, 62, 62, 62, 62, 62, 62, 62, 62, 62, 61, 61, 61, 61, 61,
    61, 61, 61, 61, 61, 60, 60, 60, 60, 60, 60, 60, 60, 60, 59, 59,
    59, 59, 59, 59, 59, 59, 59, 58, 58, 58, 58, 58, 58, 58, 58, 58,
    58, 57, 57, 57, 57, 57, 57, 57, 57, 57, 56, 56, 56, 56, 56, 56,
    56, 56, 56, 55, 55, 55, 55, 55, 55, 55, 55, 55, 54, 54, 54, 54,
    54, 54, 54, 54, 54, 53, 53, 53, 53, 53, 53, 53, 53, 53, 52, 52,
    52, 52, 52, 52, 52, 52, 52, 51, 51, 51, 51, 51, 51, 51, 51, 51,
    50, 50, 50, 50, 50, 50, 50, 50, 50, 49, 49, 49, 49, 49, 49, 49,
    49, 49, 48, 48, 48, 48, 48, 48, 48, 48, 47, 47, 47, 47, 47, 47,
    47, 47, 46, 46, 46, 46, 46, 46, 46, 46, 46, 45, 45, 45, 45, 45,
    45, 45, 44, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43,
    43, 42, 42, 42, 42, 42, 42, 42, 41, 41, 41, 41, 41, 41, 40, 40,
    40, 40, 40, 40, 39, 39, 39, 39, 39, 39, 38, 38, 38, 38, 38, 37,
    37, 37, 37, 37, 37, 36, 36, 36, 36, 36, 35, 35, 35, 35, 34, 34,
    34, 34, 34, 33, 33, 33, 33, 32, 32, 32, 32, 31, 31, 31, 31, 30,
    30, 30, 29, 29, 29, 29, 28, 28, 28, 27, 27, 27, 27, 26, 26, 26,
    25, 25, 25, 24, 24, 24, 23, 23, 22, 22, 22, 21, 21, 21, 20, 20,
    19, 19, 19, 18, 18, 17, 17, 16, 16, 16, 15, 15, 14, 14, 13, 13,
    12, 12, 11, 11, 10, 10, 9, 9, 8, 7, 7, 6, 6, 5, 5, 4,
     3, 3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

4、软件实现

main.m

% 程序说明:
% 本程序生成ADC值0-1023的温度映射表,输出静态数组格式的整数温度值
% 修改日期:2025-04-02
% 版本:v2.0(增加统一偏移量处理)

%% 原始温度(摄氏度)和ADC值数据
Temperature_C = [-55:1:125]';
ADC_Value = [1009, 1009, 1008, 1007, 1006, 1005, 1004, 1002, 1001, 999, ...
             998, 996, 994, 992, 990, 988, 986, 984, 981, 979, ...
             976, 973, 970, 967, 964, 961, 958, 954, 950, 947, ...
             943, 939, 934, 930, 925, 920, 915, 910, 905, 899, ...
             893, 887, 881, 875, 868, 861, 854, 847, 839, 832, ...
             824, 815, 807, 798, 789, 780, 771, 762, 752, 742, ...
             732, 722, 711, 701, 690, 680, 669, 658, 647, 635, ...
             624, 613, 602, 590, 579, 568, 556, 545, 534, 522, ...
             512, 500, 489, 478, 467, 456, 445, 435, 424, 414, ...
             404, 394, 384, 374, 365, 355, 346, 337, 328, 319, ...
             310, 302, 294, 286, 278, 270, 263, 255, 248, 241, ...
             234, 227, 221, 215, 208, 202, 196, 191, 185, 180, ...
             175, 170, 165, 160, 155, 151, 146, 142, 138, 134, ...
             130, 126, 122, 119, 115, 112, 109, 106, 102, 100, ...
             97, 94, 91, 89, 86, 84, 81, 79, 77, 75, ...
             73, 70, 69, 67, 65, 63, 61, 60, 58, 56, ...
             55, 53, 52, 51, 49, 48, 47, 45, 44, 43, ...
             42, 41, 40, 39, 38, 37, 36, 35, 34, 33, ...
             32]';

% 转换为列向量
ADC_Value = ADC_Value(:);

%% 1. 多项式拟合(5-8阶)
orders = 5:8;
sse = zeros(size(orders)); 
rsquared = zeros(size(orders)); 
p = cell(size(orders)); 

for i = 1:length(orders)
    n = orders(i);
    p{i} = polyfit(ADC_Value, Temperature_C, n);
    temp_fit = polyval(p{i}, ADC_Value);
    sse(i) = sum((Temperature_C - temp_fit).^2);
    rsquared(i) = 1 - sse(i)/sum((Temperature_C - mean(Temperature_C)).^2);
end

%% 2. 选择最佳拟合
[best_rsquared, best_idx] = max(rsquared);
best_order = orders(best_idx);
best_p = p{best_idx};

%% 3. 生成ADC 0-1023的温度预测
ADC_range = uint16(0:1023)'; 
Temperature_pred = round(polyval(best_p, double(ADC_range)));

% 钳位到原始温度范围
min_temp = min(Temperature_C);
max_temp = max(Temperature_C);
Temperature_pred_clamped = min(max(Temperature_pred, min_temp), max_temp);

% 应用统一偏移量(-55℃ → 0)
offset = -min_temp;
Temperature_offset = Temperature_pred_clamped + offset;

% 转换为uint8(0-255)
Temperature_uchar = uint8(min(max(Temperature_offset, 0), 255));

%% 4. 输出C语言静态数组
fprintf('\n===== C语言静态数组 =====\n');
fprintf('// 温度值 = 存储值 - %d(统一偏移量)\n', offset);
fprintf('const uint8_t ADC_TO_TEMP[1024] = {\n');

array_str = [];
for i = 1:1024
    if mod(i-1, 16) == 0
        array_str = [array_str sprintf('    ')];
    end
    array_str = [array_str sprintf('%3d', Temperature_uchar(i))];
    if i < 1024
        array_str = [array_str ','];
    end
    if mod(i, 16) == 0 && i ~= 1024
        array_str = [array_str newline];
    end
end

fprintf('%s\n', strrep(array_str, '  ', ' ')); % 优化空格
fprintf('};\n');

%% 5. 保存完整数据(CSV格式)
result_table = table(...
    ADC_range,...
    double(Temperature_pred_clamped),...
    Temperature_uchar,...
    'VariableNames', {'ADC','Temp_C','Temp_uchar_offset'});
writetable(result_table, 'ADC_Temp_Mapping.csv');

%% 6. 数据验证
fprintf('\n===== 数据验证 =====\n');
fprintf('原始温度范围: %d℃ ~ %d℃\n', min_temp, max_temp);
fprintf('预测温度范围: %d℃ ~ %d℃\n', min(Temperature_pred_clamped), max(Temperature_pred_clamped));
fprintf('偏移量处理后的存储范围: %d ~ %d\n', min(Temperature_uchar), max(Temperature_uchar));

%% 7. 可视化验证
figure;
subplot(2,1,1);
plot(ADC_range, Temperature_pred_clamped, 'b-');
hold on;
plot(ADC_Value, Temperature_C, 'ro');
title(sprintf('ADC-温度映射 (%d阶拟合)', best_order));
xlabel('ADC值'); ylabel('温度(℃)');
legend('拟合曲线', '原始数据', 'Location','best');
grid on;

subplot(2,1,2);
% ==== 修复部分:仅计算原始ADC采样点的误差 ====
% 重新生成原始ADC点对应的预测温度
temp_fit_original = round(polyval(best_p, ADC_Value)); 
temp_fit_clamped = min(max(temp_fit_original, min_temp), max_temp); % 钳位
error = temp_fit_clamped - Temperature_C; % 正确计算误差
histogram(error);
% ============================================
title('原始数据点温度预测误差分布');
xlabel('误差(℃)'); ylabel('频数');
grid on;

5、温度表调用方法

// 1. 确保ADC值在有效范围内
    if (adc_value < 0 || adc_value >= 1024) {
        return -128; // 返回错误值(超出范围)
    }
    
    // 2. 查找温度(已应用偏移量)
    uint8_t temp_offset = ADC_TO_TEMP[adc_value];
    
    // 3. 减去偏移量,得到实际温度
    int8_t temp_c = temp_offset - 55; // 偏移量为55
  • 偏移量处理

    • 数组值是实际温度加上偏移量 55(即 -55℃ 对应 0125℃ 对应 180)。
    • 使用时必须减去偏移量 55,以得到实际温度。
  • ADC值范围

    • ADC值必须在 0 到 1023 之间。超出范围时,函数返回 -128 表示错误。
  • 数据类型

    • uint8_t 用于存储温度(偏移量后)。
    • int8_t 用于存储实际温度(带符号)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值