单片机测量NTC热敏电阻温度的方法(含程序代码)

2023-05-16

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);
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

单片机测量NTC热敏电阻温度的方法(含程序代码) 的相关文章

随机推荐

  • Mysql(16)——日志

    前言 我们之前了解过redo log和undo log xff0c 他们是作用在InnoDb存储引擎层的 xff0c 今天我们来讲讲服务层的其他日志类型 一 错误日志 错误日志是 MySQL 中最重要的日志之一 xff0c 它记录了当 my
  • Mysql(17)——优化

    前言 一 SQL和索引优化 二 应用优化 除了优化SQL和索引 xff0c 很多时候 xff0c 在实际生产环境中 xff0c 由于数据库服务器本身的性能局限 xff0c 就必须要对上层的应用来进行一些优化 xff0c 使得上层应用访问数据
  • 项目——C++实现数据库连接池

    前言 在学习Mysql的时候 xff0c 我们都有这个常识 xff1a 对于DB的操作 xff0c 其实本质上是对于磁盘的操作 xff0c 如果对于DB的访问次数过多 xff0c 其实就是涉及了大量的磁盘IO xff0c 这就会导致MYsq
  • Redis入门——发展历程及NoSQL

    前言 随着社会的发展 xff0c 数据存储经历了诸多的过程 xff0c 这篇文章就是介绍Redis的发展由来 xff1a 1 单机Mysql时代 这种模式存在以下的瓶颈 xff1a 数据量太大 xff0c 一个机器存放不下数据的索引太大 x
  • Redis(1)——基本命令及数据类型(5+3)

    Redis的基本概念 Remote Dictionary Server xff1a 远程字典服务Redis 是一个开源 xff08 BSD许可 xff09 的 xff0c 内存中的数据结构存储系统 xff0c 它可以用作数据库 缓存和消息中
  • Redis(2)——事务机制

    Redis的事务机制 Redis的事务本质 xff1a 一组命令的集合一个事务中的所有命令都会都被序列化 xff0c 在事务执行的过程中 xff0c 会按照顺序执行 xff01 一次性 顺序性 排他性 执行一系列的命令Redis没有事务隔离
  • Redis(3)—— 持久化、发布订阅

    持久化 Redis是内存数据库 xff0c 如果不将内存中的数据库状态保存到磁盘中 xff0c 那么一旦服务器进程退出 xff0c 服务器中的数据库状态也会消失 所以Redis提供了持久化的功能 1 RDB xff08 Redis Data
  • Redis(4)——主从复制

    Redis主从复制 主从复制 xff1a 指的是将一个Redis服务器的数据 xff0c 复制到其他的Redis服务器 前者称为主节点 xff08 master leader xff0c 后者称为从节点 xff08 slave follow
  • Redis(5)——缓存穿透和雪崩

    概要 Redis缓存的使用 xff0c 极大的提高了应用程序的性能和效率 xff0c 特别是数据查询等 但同时 xff0c 它也带来了一些问题 其中 xff0c 最主要的问题就是数据一致性 xff0c 从严格意义上来讲 xff0c 这个问题
  • 复习:结构体大小的内存对齐问题

    内存对齐 内存对齐是指 xff1a 任意单个类型的数据都需要存放在能被它本身大小所能整除的地址上 基本类型的大小 char 1 short 2 int 4 long 4 long long 8 float 4 double 8 指针 4 8
  • 0.一些自己初学Solidworks的疑惑

    1 为什么要选择学习SolidWorks 首先 作为初学者 我们对一个东西并不是很了解 那么就需要别人来教我们 对吧 这些人可以是老师 可以是同学 可以是师傅 可以是网络上热心肠的大神 可以是一些培训机构 等等 首先呢 学习三维设计软件 看
  • LInux——五种IO模型

    Linux中的IO简述 IO主要分为以下的三种 xff1a 内存IO网络IO磁盘IO 通常我们所说的IO是后两者 xff0c Linux中无法直接操作IO设备 xff0c 必须通过系统调用请求kernal来协助完成IO的动作 xff0c 内
  • 复习:Linux中的软连接和硬连接

    前言 首先我们先来复习以下Linux的文件系统 Linux的文件系统是EXT4 以EXT4文件系统格式化磁盘时 xff0c 将磁盘分成了三个区 xff0c 分别是 xff1a 1 superblock xff1a 记录文件系统的整体信息 x
  • 复习:字节对齐的原则

    为什么需要字节对齐 xff1f 现代计算机中内存空间都是按照byte划分的 xff0c 从理论上讲似乎对任何类型的变量的访问可以从任何地址开始 xff0c 但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问 xff0c 这就需要各
  • Reactor模型

    前言 首先让我们来回顾一下select poll和epoll是如何获取网络事件的 xff1a 在获取事件时 xff0c 先把我们要关心的连接传给内核 xff0c 再由内核检测 xff1a 若没有事件发生 xff0c 线程只需阻塞在这个系统调
  • Proactor模型

    前言 上一篇讲解的Reaactor是非阻塞的同步网络模式 xff0c 而Proactor是异步网络模式 至于异步IO怎么理解 xff1a 可以参考我的这一篇博客 xff1a Linux的五种IO模型 理解之后 xff1a 你就会感受到 xf
  • STL空间配置器(一级配置器及二级配置器)

    前言 在我们日常使用STL中的容器时 xff0c 我们是几乎感受不到空间配置器的存在 xff0c 因为他一直在默默工作 xff0c 我们在之前的这一篇博客中也大概介绍过 xff1a C 43 43 xff08 21 xff09 vector
  • HTTP各个版本的区别

    HTTP 1 0 短连接版本 HTTP 1 0规定浏览器与服务器只保持短暂的连接 xff0c 即每一次请求都需要与服务器建立一次TCP连接 xff0c 服务器完成请求处理后立即断开TCP连接 服务器不会跟踪每个客户也不记录过去的请求 xff
  • 实时时钟芯片DS1307的使用及驱动代码

    DS1307实时时钟芯片的介绍及驱动代码 目录 一 DS1307是什么 xff1f 二 DS1307的功能 三 DS1307的寄存器 四 代码 1 读出数据 2 写入数据 3 时间初始化设置 4 获取当前时间 五 注意事项 总结 一 DS1
  • 单片机测量NTC热敏电阻温度的方法(含程序代码)

    1 NTC介绍 NTC是负温度系数热敏电阻 xff0c 随着温度的升高 xff0c NTC的阻值会呈非线性的下降 2 硬件连接 这里采用100k 3950的热敏电阻 xff0c 100k代表的是在25 下的标准阻值 xff0c 3950是热