b3950热敏电阻的(二分查找)查表法实现

b3950热敏电阻的(二分查找)查表法

    • 开发环境
    • 通过热敏电阻采集温度有两种方法:
      • 一种查表法的完整实现
    • 展望

开发环境

本文的基于如下开发环境,若开发环境不同可能不能达到预期效果。

IDE:AtmelStudio 7
toochain:avr-gcc 
MCU  :atmega128A

通过热敏电阻采集温度有两种方法:

1.公式计算法,根据转换公式直接通过测量得到的阻值计算出温度;
2.查表法,也是本例采用的算法,使用
由于嵌入式式设备MCU的计算能力比较弱(浮点运算比较慢),所以通常采用查表法。

这个算法的功能:根据电阻阻值获取对应的温度。
这个算法可以归类在二分算法下。
难点:查找和比较的对象是浮点数,并且阻值不连续,所以要考虑阻值在两个典型阻值之间的问题。

一种查表法的完整实现

如下编码在avr-gcc中实现,测试。

#include "b3950.h"
#include 

typedef struct 
{
	int16 t;
	float r;
}sToR;

const sToR tr_array[] PROGMEM = 
{
{-20,97.8396f},
{-19,92.3020},
{-18,87.1124},
{-17,82.2471},
{-16,77.6837},
{-15,73.4018},
{-14,69.3823},
{-13,65.6077},
{-12,62.0616},
{-11,58.7288},
{-10,55.5953},
{-9	,52.6480},
{-8	,49.8747},
{-7	,47.2643},
{-6	,44.8062},
{-5	,42.4906},
{-4	,40.3086},
{-3	,38.2516},
{-2	,36.3117},
{-1	,34.4817},
{0	,32.7547},
{1	,31.1243},
{2	,29.5847},
{3	,28.1301},
{4	,26.7556},
{5	,25.4562},
{6	,24.2274},
{7	,23.0650},
{8	,21.9650},
{9	,20.9239},
{10	,19.9380},
{11	,19.0041},
{12	,18.1193},
{13	,17.2807},
{14	,16.4857},
{15	,15.7317},
{16	,15.0164},
{17	,14.3376},
{18	,13.6933},
{19	,13.0816},
{20	,12.5005},
{21	,11.9485},
{22	,11.4239},
{23	,10.9252},
{24	,10.4510},
{25	,10.0000},
{26	,9.5709 },
{27	,9.1626 },
{28	,8.7738 },
{29	,8.4037 },
{30	,8.0512 },
{31	,7.7154 },
{32	,7.3953 },
{33	,7.0903 },
{34	,6.7995 },
{35	,6.5221 },
{36	,6.2576 },
{37	,6.0051 },
{38	,5.7642 },
{39	,5.5342 },
{40	,5.3146 },
{41	,5.1049 },
{42	,4.9045 },
{43	,4.7130 },
{44	,4.5300 },
{45	,4.3551 },
{46	,4.1878 },
{47	,4.0278 },
{48	,3.8748 },
{49	,3.7283 },
{50	,3.5882 },
{51	,3.4540 },
{52	,3.3255 },
{53	,3.2025 },
{54	,3.0846 },
{55	,2.9717 },
{56	,2.8635 },
{57	,2.7597 },
{58	,2.6603 },
{59	,2.5649 },
{60	,2.4734 },
{61	,2.3856 },
{62	,2.3014 },
{63	,2.2206 },
{64	,2.1431 },
{65	,2.0686 },
{66	,1.9970 },
{67	,1.9283 },
{68	,1.8623 },
{69	,1.7989 },
{70	,1.7380 },
{71	,1.6794 },
{72	,1.6231 },
{73	,1.5689 },
{74	,1.5168 },
{75	,1.4667 },
{76	,1.4185 },
{77	,1.3722 },
{78	,1.3275 },
{79	,1.2845 },
{80	,1.2431 },
{81	,1.2033 },
{82	,1.1649 },
{83	,1.1279 },
{84	,1.0923 },
{85	,1.0580 },
{86	,1.0249 },
{87	,0.9930 },
{88	,0.9623 },
{89	,0.9326 },
{90	,0.9040 },
{91	,0.8764 },
{92	,0.8498 },
{93	,0.8241 },
{94	,0.7994 },
{95	,0.7754 },
{96	,0.7523 },
{97	,0.7300 },
{98	,0.7085 },
{99	,0.6877 },
{100,0.6676 },
{101,0.6482 },
{102,0.6295 },
{103,0.6113 },
{104,0.5938 },
{105,0.5769 },
{106,0.5605 },
{107,0.5447 },
{108,0.5293 },
{109,0.5145 },
{110,0.5002 },
{111,0.4863 },
{112,0.4729 },
{113,0.4599 },
{114,0.4474 },
{115,0.4352 },
{116,0.4234 },
{117,0.4120 },
{118,0.4009 },
{119,0.3902 },
{120,0.3799 },
{121,0.3698 },
{122,0.3601 },
{123,0.3506 },
{124,0.3415 },
{125,0.3326 },
{126,0.3240 },
{127,0.3157 },
{128,0.3076 },
{129,0.2998 },
{130,0.2922 },
{131,0.2848 },
{132,0.2776 },
{133,0.2707 },
{134,0.2640 },
{135,0.2574 },
{136,0.2511 },
{137,0.2449 },
{138,0.2389 },
{139,0.2331 },
{140,0.2274 },
{141,0.2220 },
{142,0.2166 },
{143,0.2114 },
{144,0.2064 },
{145,0.2015 },
{146,0.1968 },
{147,0.1922 },
{148,0.1877 },
{149,0.1833 },
{150,0.1791 },
{151,0.1749 },
{152,0.1709 },
{153,0.1670 },
{154,0.1632 },
{155,0.1595 },
{156,0.1559 },
{157,0.1524 },
{158,0.1490 },
{159,0.1457 },
{160,0.1425 },
{161,0.1394 },
{162,0.1363 },
{163,0.1333 },
{164,0.1304 },
{165,0.1276 },
{166,0.1249 },
{167,0.1222 },
{168,0.1196 },
{169,0.1170 },
{170,0.1146 },
{171,0.1121 },
{172,0.1098 },
{173,0.1075 },
{174,0.1053 },
{175,0.1031 },
{176,0.1010 },
{177,0.0989 },
{178,0.0969 },
{179,0.0949 },
{180,0.0930 },
{181,0.0911 },
{182,0.0893 },
{183,0.0875 },
{184,0.0858 },
{185,0.0841 },
{186,0.0824 },
{187,0.0808 },
{188,0.0792 },
{189,0.0777 },
{190,0.0762 },
{191,0.0747 },
{192,0.0733 },
{193,0.0719 },
{194,0.0705 },
{195,0.0692 },
{196,0.0679 },
{197,0.0666 },
{198,0.0654 },
{199,0.0642 },
};
static volatile float rMid,tempR,tempDeltaL,tempDeltaR;
static volatile	u8 left,right,mid;
static volatile	int16 t;
int16 FindTempByRes(float res)
{	

	
	
	t = 0;
	rMid = 0;
	left = mid = 0;
	right = 219;
	
	while(left<right)
	{
		mid = (left+right)/2;
		rMid = pgm_read_float(&(tr_array[mid].r));//tr_array[mid].r;//pgm_read_float(&(tr_array[mid].r));
		

		if(rMid>res){//数组索引越大阻值越小
			//检查最大值
			tempR = pgm_read_float(&(tr_array[mid + 1].r));
			if(res>tempR)//tr_array[mid+1].r < res < tr_array[mid].r
			{
				tempDeltaL = rMid - res;
				tempDeltaR = res - tempR;
				if(tempDeltaL < tempDeltaR)
				{
					t = pgm_read_word(&(tr_array[mid].t));
					break;
				}else
				{
					t = pgm_read_word(&(tr_array[mid+1].t));
					break;
				}
			}else//不在mid和mid+1之间
			{	
				left = mid+1;
			}
		}else if(rMid<res){
			tempR = pgm_read_float(&(tr_array[mid - 1].r));
			if(tempR>res)//tr_array[mid].r < res < tr_array[mid-1].r
			{
				tempDeltaL = tempR - res;
				tempDeltaR = res - rMid;
				if(tempDeltaL < tempDeltaR)
				{
					t = pgm_read_word(&(tr_array[mid-1].t));
					break;
				}else
				{
					t = pgm_read_word(&(tr_array[mid].t));
					break;
				}				
			}else//不在mid及mid-1之间
			{
				right = mid-1;
			}
		}else{
			t = pgm_read_word(&(tr_array[mid].t));//tr_array[mid].t;//pgm_read_word(&(tr_array[mid].t));
			break;
		}

		if(left == right)//
		{
			t = pgm_read_word(&(tr_array[left].t));
			break;
		}
	}
	

	return t;
}

展望

更改与平台相关的代码(pgm_read_float,pgm_read_word),可以移植到其他平台,对于同类电阻而言,编制相应的表来实现支持,算法不变。

你可能感兴趣的:(AVR,嵌入式)