一段测试好的NTC RT表插温度的算法, 采用二分法, RT表是倒序的(大到小排列)

const u16 TABLE_mV[] = {
	2913,2900,2887,2875,2862,2848,2835,2822,2808,2794,2780,		//8C-18C
	2766,2752,2738,2724,2710,2696,2681,2667,2652,2637,2623,
	2608,2593,2579,2564,2549,2535,2520,2505,2491,2477,2462,
	2448,2434,2420,2406,2392,2378,2365,2351,2338,2325,2312,
	2299,2286,2274,2261,2249,2237,2225,2213,2202,2191,2179,
	2168,2157,2147,2136,2126,2116,2106,2096,2087,2077,2068,
	2059,2050,2042,2033,2025,2017,2009,2001,1993,1986,1979,
	1971,1964,1957,1951,1944,1937,1931,1925,1919,1913,1907,		//84C-94C
};

#define START_TEMP	8	
u8 search_temp(u16 mV) 
{
	if((mV > 3100) || (mV < 1700))
		return 25;
	
    if (mV >= TABLE_mV[0]) 
		return START_TEMP;

    if (mV <= TABLE_mV[ARRAY_LAST(TABLE_mV)]) 
		return (START_TEMP + ARRAY_LAST(TABLE_mV));
    
    u8 min = 0;
	u8 max = ARRAY_LAST(TABLE_mV);
	u8 half = ARRAY_SIZE(TABLE_mV) >> 1;
	u8 mid;
    while (half) 
	{
		half = (max - min) >> 1;
        mid = min + half;

        if (mV < TABLE_mV[mid]) 
		{
			min = mid;
		}
        else if (mV > TABLE_mV[mid]) 
		{
			max = mid;
		}
		else
		{
			return mid + START_TEMP;
		}
    }

    if ((TABLE_mV[min] - mV) < (mV - TABLE_mV[max])) 
        return min + START_TEMP;
    else 
        return max + START_TEMP;
}

u16 adc2mv(u16 adc)
{
	u32 mv = 3300 * adc / 4095;
	return mv;
}

void getTemperature(void)
{
	u16 t = search_temp(adc2mv(AD_BAT_NTC)); 
	ana.Tbat = (ana.Tbat + t) >> 1;

	t = search_temp(adc2mv(AD_PCB_NTC));
	ana.Tpcb = (ana.Tpcb + t) >> 1;
}

上面的基于电压mV查表温度的, 下面的基于adc:


const u16 RT[] =
{                   //'C       Kohm          
    2997,           //0		    27.31
    2819,           //5		    22.09
    2631,           //10		17.98
    2438,           //15		14.71
    2242,           //20		12.10
    2048,           //25		10
    1859,           //30		8.31
    1676,           //35		6.93
    1507,           //40		5.82
    1347,           //45		4.9
    1201,           //50		4.15
    1068,           //55		3.53
    950             //60		3.02
};

#define ARRAY_SIZE(arr)	(sizeof(arr) / sizeof(arr[0]))
#define ARRAY_LAST(arr)	(ARRAY_SIZE(arr) - 1)
#define TEMP_START	0	
#define TEMP_STEP	5
u8 search_temp(u16 adc) 
{
	if(adc > 3800)      //ntc open?
		return 254;     //fail ntc

	if(adc < 500)	    //ntc short?
		return 255;     //fail ntc

    if (adc >= RT[0]) 
		return TEMP_START;

    if (adc <= RT[ARRAY_LAST(RT)]) 
		return TEMP_START + (ARRAY_LAST(RT) * TEMP_STEP);
    
    u8 min = 0;
	u8 max = ARRAY_LAST(RT);
	u8 half = ARRAY_SIZE(RT) >> 1;
	u8 mid;
    while (half) 
	{
		half = (max - min) >> 1;
        mid = min + half;

        if (adc < RT[mid]) 
		{
			min = mid;
		}
        else if (adc > RT[mid]) 
		{
			max = mid;
		}
		else  //==
		{
			return TEMP_START + (mid * TEMP_STEP);
		}
    }

    if ((RT[min] - adc) < (adc - RT[max])) 
        return TEMP_START + (min * TEMP_STEP);
    else 
        return TEMP_START + (max * TEMP_STEP);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值