赞
踩
NTC是负温度系数热敏电阻,随着温度的升高,NTC的阻值会呈非线性的下降。
这里采用100k 3950的热敏电阻,100k代表的是在25℃下的标准阻值,3950是热敏电阻的B值,B值与电阻温度系数正相关,也就是说B值越大,其电阻温度系数也就越大。
网上查找我们所选用NTC对应的R-T对照表,也就是温度阻值对照表。根据R-T表绘制出的曲线图发现这是一个非线性曲线,所以我们很难求解。这个时候我们可以采用曲线拟合的方法,划分成很多个区间,每个区间都是一段小直线,就类比分段函数,区间划分的越多结果就越精确。这样我们只要知道NTC的阻值,找到对应的区间,带入一元一次方程求解就可以计算出对应的温度值。NTC的阻值可以通过单片机ADC采集100K电阻两端电压,然后根据电阻分压来算出。
下图是用Excel表绘制出的曲线图,Y轴是温度,单位℃,X轴是电阻值,单位KΩ。
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);
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。