单片机测量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);
}

物联沃分享整理
物联沃-IOTWORD物联网 » 单片机测量NTC热敏电阻温度的方法及程序代码详解

发表评论