单片机测量NTC热敏电阻温度的方法(含程序代码)
·
1、NTC介绍
NTC是负温度系数热敏电阻,随着温度的升高,NTC的阻值会呈非线性的下降。
2、硬件连接
这里采用100k 3950的热敏电阻,100k代表的是在25℃下的标准阻值,3950是热敏电阻的B值,B值与电阻温度系数正相关,也就是说B值越大,其电阻温度系数也就越大。
3、 温度计算
网上查找我们所选用NTC对应的R-T对照表,也就是温度阻值对照表。根据R-T表绘制出的曲线图发现这是一个非线性曲线,所以我们很难求解。这个时候我们可以采用曲线拟合的方法,划分成很多个区间,每个区间都是一段小直线,就类比分段函数,区间划分的越多结果就越精确。这样我们只要知道NTC的阻值,找到对应的区间,带入一元一次方程求解就可以计算出对应的温度值。NTC的阻值可以通过单片机ADC采集100K电阻两端电压,然后根据电阻分压来算出。
下图是用Excel表绘制出的曲线图,Y轴是温度,单位℃,X轴是电阻值,单位KΩ。
4、代码
1、本次需要测量的温度范围为-30~90度之间,划分为120个区间,网上查找3950 100k热敏电阻所对应的R-T对照表,把各温度对应的电阻值写入一个数值中。
// b值为3950 的NTC阻值表,单位为10Ω
uint32_t NTC[121]=
{
178797, //-30
167960, //-29
157850, //-28
148415, //-27
139606, //-26
131377, //-25
123686, //-24
116495, //-23
109769, //-22
103474, //-21
97580, //-20
92059, //-19
86886, //-18
82036, //-17
77487, //-16
73218, //-15
69212, //-14
65449, //-13
61915, //-12
58593, //-11
55470, //-10
52532, //-9
49768, //-8
47166, //-7
44715, //-6
42407, //-5
40232, //-4
38182, //-3
36248, //-2
34423, //-1
32701, //0
31076, //1
29541, //2
28090, //3
26720, //4
25424, //5
24198, //6
23039, //7
21942, //8
20903, //9
19920, //10
18988, //11
18105, //12
17268, //13
16475, //14
15722, //15
15008, //16
14331, //17
13688, //18
13077, //19
12497, //20
11946, //21
11422, //22
10924, //23
10450, //24
10000, //25
9571, //26
9163, //27
8774, //28
8405, //29
8052, //30
7717, //31
7397, //32
7092, //33
6801, //34
6524, //35
6259, //36
6007, //37
5766, //38
5536, //39
5316, //40
5106, //41
4906, //42
4714, //43
4531, //44
4356, //45
4188, //46
4028, //47
3875, //48
3728, //49
3588, //50
3454, //51
3325, //52
3202, //53
3084, //54
2970, //55
2862, //56
2758, //57
2658, //58
2563, //59
2471, //60
2383, //61
2299, //62
2218, //63
2140, //64
2065, //65
1994, //66
1925, //67
1859, //68
1795, //69
1734, //70
1675, //71
1619, //72
1564, //73
1512, //74
1462, //75
1414, //76
1367, //77
1322, //78
1279, //79
1238, //80
1198, //81
1159, //82
1122, //83
1086, //84
1052, //85
1019, //86
987, //87
956, //88
926, //89
898 //90
};
2、温度计算代码如下:
#define REF_RES_VAL 10000 //参考电阻为100K=10000*10, 单位是10Ω
uint16_t VCC,NTC1_VOLT,NTC2_VOLT;
uint16_t get_value[8];
extern uint32_t NTC[121];
uint16_t Voltage_Samples(adc_channel_t ch)
{
uint16_t InterrefVolt_ADC,ANI2_ADC,ANI3_ADC;
ADC_Converse(ADC_INTERREFVOLT, 8 , get_value);
InterrefVolt_ADC = ADC_MidAvg_Filter(get_value,8);
VCC = 1450*4096/InterrefVolt_ADC;
// printf("VCC = %dmv\r\n",VCC);
if(ch == ADC_CHANNEL_2)
{
ADC_Converse(ADC_CHANNEL_2, 8 , get_value);
ANI2_ADC = ADC_MidAvg_Filter(get_value,8);
NTC1_VOLT = ANI2_ADC*VCC/4096;
ADC_Stop();
// printf("NTC1_VOLT = %dmv\r\n",NTC1_VOLT);
return NTC1_VOLT;
}
if(ch == ADC_CHANNEL_3)
{
ADC_Converse(ADC_CHANNEL_3, 8 , get_value);
ANI3_ADC = ADC_MidAvg_Filter(get_value,8);
NTC2_VOLT = ANI3_ADC*VCC/4096;
ADC_Stop();
// printf("NTC2_VOLT = %dmv\r\n",NTC2_VOLT);
return NTC2_VOLT;
}
return 0;
}
uint16_t ADC_MidAvg_Filter(uint16_t *buf, uint8_t num)
{
uint8_t i, j;
uint16_t tmp;
uint32_t sum;
/* sort the value from small to large */
for(i = 0; i < num; i++)
{
for(j = 0; j < ((num - 1) - i); j++)
{
if(buf[j] > buf[j + 1])
{
tmp = buf[j];
buf[j] = buf[j + 1];
buf[j + 1] = tmp;
}
}
}
/* Remove the smallest and largest values, then take the average */
sum = 0;
for(i = 2; i < (num - 2); i++)
{
sum += buf[i];
}
tmp = (uint16_t) (sum / (num - 4));
return (tmp);
}
/*************************************************************************************************
* 函数名: CalcuTemp
* 参 数: 无
* 返回值: 无
* 描 述: 根据计算的阻值来查表,获取对应温度
*************************************************************************************************/
int16_t CalcuTemp(uint16_t getdata)
{
uint8_t i;
uint8_t TempeMiddle=60;
int16_t Temperature;
uint32_t resis;
resis = (uint32_t)(VCC-getdata)*REF_RES_VAL/getdata; //计算热敏电阻的阻值
// printf("Tempcalcu = %d\r\n",Tempcalcu);
if(resis >= NTC[0])
{
Temperature = -300;
}
else if(resis <= NTC[120])
{
Temperature = 900;
}
else
{
i = TempeMiddle;
if(resis > NTC[i])
{
for(i=TempeMiddle-1; i>=0; i--)
{
if(resis <= NTC[i]) //NTC[i+1] < resis < NTC[i]
{
break;
}
}
}
else
{
for(i=TempeMiddle+1; i<120; i++)
{
if(resis > NTC[i]) //NTC[i-1] < resis < NTC[i]
{
break;
}
}
i--;
}
TempeMiddle = i;
Temperature = (uint16_t)(TempeMiddle-30)*10+(NTC[i]-resis)*10/(NTC[i]-NTC[i+1]);
}
return Temperature;
}
void Get_Temperature(void)
{
float Temp1,Temp2;
Voltage_Samples(ADC_CHANNEL_2);
Voltage_Samples(ADC_CHANNEL_3);
Temp1= CalcuTemp(NTC1_VOLT)/10.0;
Temp2= CalcuTemp(NTC2_VOLT)/10.0;
printf("Temp1 = %.1f℃\r\n",Temp1);
printf("Temp2 = %.1f℃\r\n",Temp2);
}
更多推荐
已为社区贡献1条内容
所有评论(0)