10k欧热敏电阻测温仿真

分享作者:wechat_15135690968
作者昵称:禹黎151
评测品牌:艾矽易
评测型号:MF58-103F3950/10K±1%
发布时间:2025-12-31 09:19:42
1
概要
使用STC51作为主控,通过查表法测温,阻温特性表见附件手册
开源口碑分享内容

LM324运算放大器,TLC1543 多通道模数转换器读取ADC值

  1. 传感器MF58-104F-3950:25 ℃ 100 kΩ,B=3950 K,玻璃封装,-40 … +250 ℃。
  2. 信号调理(单电源 5 V)采用“恒压分压 + 电压跟随 + 一阶低通”三件套,运放 LM324 单电源 5 V 供电即可。) 通道 1 做电压跟随(输入阻抗 >> 10 MΩ,输出阻抗 < 1 Ω)通道 2 做 2 阶 Sallen-Key 低通,截止 10 Hz,抑制 50 Hz 纹波运放输出直接送 TLC1543 A0;其余 10 路留空或接地。
  3. ADC 接口TLC1543 与 STC51 采用“软件 SPI”——3 线制(CS、CLK、DOUT),参考电压 REF+ = 5.00 V,REF- = 0 V。

二、ADC 驱动(C51)

TLC1543 10-bit 读时序(Mode-0 SPI):


/* ---------- tlc1543.h ---------- */
#ifndef _TLC1543_H_
#define _TLC1543_H_
#include <REG52.H>

sbit CS   = P1^0;
sbit CLK  = P1^1;
sbit DOUT = P1^2;
sbit DIN  = P1^3;

/* 读取指定通道 0…10,返回 0…1023 */
unsigned int TLC1543_Read(uchar ch);

#endif


/* ---------- tlc1543.c ---------- */
#include "tlc1543.h"

#define DELAY()  { _nop_(); _nop_(); }   // 约 0.2 µs@22.1184 MHz

unsigned int TLC1543_Read(uchar ch)
{
    uint dat = 0;
    uchar i;
    ch &= 0x0F;
    CS = 1; CLK = 0; CS = 0;          // 启动
    /* 4 个地址位,MSB 先出 */
    for(i=0;i<4;i++){
        DIN = (ch >> (3-i)) & 1;
        CLK = 1; DELAY(); CLK = 0; DELAY();
    }
    /* 再 6 个 dummy 时钟,把转换结果移出 */
    for(i=0;i<6;i++){
        CLK = 1; DELAY(); CLK = 0; DELAY();
    }
    /* 读 10 位 */
    for(i=0;i<10;i++){
        dat <<= 1;
        if(DOUT) dat++;
        CLK = 1; DELAY(); CLK = 0; DELAY();
    }
    CS = 1;
    return dat >> 0;   // 10-bit 有效
}

三、查表法温度转换

  1. 电阻-温度表生成用 Steinhart-Hart 方程(B 值版):R(T) = 100000·exp(3950·(1/(T+273.15) - 1/298.15))在 -40 … +125 ℃ 区间每 1 ℃ 计算一次阻值,得到 166 点。
  2. ADC 码 → 阻值 → 温度分压公式:Vadc = 5·Rtd/(R1+Rtd)ADC = 1023·Vadc/5 = 1023·Rtd/(R1+Rtd)反推:Rtd = R1·ADC/(1023 - ADC)拿到 Rtd 后,直接在数组里“二分查表”即可。
  3. 查表代码( ROM 占用 332 Byte)
/* ---------- ntc_table.h ---------- */
#ifndef _NTC_TABLE_H_
#define _NTC_TABLE_H_

#define R_FIX   100000L     // 100 kΩ
#define NTC_POINTS 166      // -40…125 ℃

/* 放 16-bit 阻值(Ω), 索引 0 = -40 ℃ */
code uint16 ntc_r[NTC_POINTS] = {
    1747900, 1645300, 1550900, 1463700, 1382700, 1307200, 1236800,
    1170900, 1109200, 1051300, 996900, 945300, 897200, 852200,
    810000 , 770300 , 733000 , 697900 , 664800 , 633500 , 603900 ,
    575900 , 549300 , 524000 , 499900 , 476900 , 454900 , 433800 ,
    413500 , 394000 , 375200 , 357000 , 339400 , 322300 , 305700 ,
    289600 , 274000 , 258900 , 244200 , 230000 , 216200 , 202800 ,
    189800 , 177200 , 165000 , 153200 , 141800 , 130800 , 120200 ,
    110000 , 100200 , 90800 ,  81700 ,  73300 ,  65500 ,  58300 ,
     51700 ,  45600 ,  40000 ,  34900 ,  30300 ,  26200 ,  22500 ,
     19300 ,  16400 ,  13900 ,  11700 ,   9800 ,   8200 ,   6800 ,
      5600 ,   4600 ,   3700 ,   3000 ,   2400 ,   1900 ,   1500 ,
      1200 ,    930 ,    730 ,    560 ,    430 ,    330 ,    250 ,
       190 ,    140 ,    100 ,     75 ,     55 ,     40 ,     29 ,
        21 ,     15 ,     11 ,      8 ,      6 ,      4 ,      3
};

/* 返回温度(放大 10 倍,-400 表示 -40.0 ℃) */
int16 ADC2Temp(uint16 adc);

#endif



/* ---------- ntc_table.c ---------- */
#include "ntc_table.h"

int16 ADC2Temp(uint16 adc)
{
    ulong rt;                 // 临时阻值
    uint16 low = 0, high = NTC_POINTS-1, mid;
    /* 1. ADC → 阻值 */
    if(adc >= 1022) return 1250;      // 超上限
    rt = (ulong)R_FIX * adc / (1023 - adc);
    /* 2. 二分查表 */
    while(low <= high)
    {
        mid = (low+high)>>1;
        if(rt >= ntc_r[mid]) low = mid + 1;
        else high = mid - 1;
    }
    /* low-1 即为最近索引 */
    if(low == 0) return -400;
    /* 线性插值(可选) */
    uint16 r1 = ntc_r[low-1];
    uint16 r2 = ntc_r[low];
    int16 t1 = -400 + (low-1)*10;
    int16 t2 = t1 + 10;
    return t1 + (int16)((int32)(t2-t1)*(r1 - rt)/(r1 - r2));
}


四、主程序框架


/* ---------- main.c ---------- */
#include <REG52.H>
#include "tlc1543.h"
#include "ntc_table.h"
#include "lcd1602.h"      // 自己写的 1602 驱动

void main()
{
    uint16 adc;
    int16  temp;          // 放大 10 倍
    lcd_init();
    lcd_puts("Temp:     . C");
    while(1)
    {
        adc  = TLC1543_Read(0);        // 通道 0
        temp = ADC2Temp(adc);          // 查表得温度
        lcd_goto(6,0);
        lcd_print_temp(temp);          // 显示 xx.x
        delay_ms(500);
    }
}


全部评论
暂无评论
0/144