本文的基于如下开发环境,若开发环境不同可能不能达到预期效果。
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),可以移植到其他平台,对于同类电阻而言,编制相应的表来实现支持,算法不变。