侧边栏壁纸
博主头像
塞塞哇 博主等级

开源创客

  • 累计撰写 38 篇文章
  • 累计创建 9 个标签
  • 累计收到 9 条评论

目 录CONTENT

文章目录

NTC 热敏电阻温度检测

塞塞蛙
2023-08-05 / 0 评论 / 0 点赞 / 142 阅读 / 0 字

NTC 热敏电阻温度检测

本文将讲解如何使用温控热敏电阻NTC原件使用单片机的ADC去测量温度

前言

NTC热敏电阻(Negative Temperature Coefficient Thermistor)是一种特殊类型的电阻器,其电阻值随温度的变化而变化。具体来说,当温度升高时,NTC热敏电阻的电阻值会下降;反之,当温度降低时,电阻值会上升。这种负温度系数(NTC)特性使得NTC热敏电阻在测量温度、温度补偿以及温度控制等应用中非常有用。

NTC热敏电阻通常由半导体材料制成,其电阻值变化是由于半导体材料中载流子浓度的变化引起的。随着温度的升高,载流子浓度增加,导致电阻值下降,反之亦然。

NTC热敏电阻广泛应用于各种领域,包括以下几个方面:

  1. 温度测量和控制:将NTC热敏电阻用作温度传感器,可以通过测量电阻值的变化来推断环境温度。这在许多设备中都有应用,例如家电、汽车、医疗设备等。

  2. 过热保护:在一些设备中,NTC热敏电阻可以用于检测过热情况,从而触发保护机制,防止设备损坏。

  3. 温度补偿:某些电路元件的性能可能会随温度变化而改变。使用NTC热敏电阻可以进行温度补偿,使得电路在不同温度下保持稳定的工作。

  4. 气候控制:在气象站、温室和 HVAC(暖通空调)系统中,NTC热敏电阻用于监测和控制环境温度。

总之,NTC热敏电阻是一种重要的温度敏感元件,具有广泛的应用领域,可以在许多需要温度测量、控制和补偿的场景中发挥作用。

NTC热敏电阻在温度测量和控制等应用中具有一些优点和缺点,让我们来看一下:

优点:

  1. 高灵敏度: NTC热敏电阻对温度的变化非常敏感,这使得它们在测量小范围温度变化时非常有效。

  2. 小尺寸: NTC热敏电阻相对来说比较小,可以方便地集成到各种设备和电路中。

  3. 成本较低: 相比于其他温度传感器,NTC热敏电阻的制造成本相对较低,因此在成本敏感的应用中具有竞争优势。

  4. 实时响应: 由于热敏电阻是一种被动元件,它们对温度变化的响应几乎是实时的,不需要外部激励信号。

缺点:

  1. 非线性: NTC热敏电阻的电阻-温度关系通常是非线性的,这意味着在将电阻值转换为温度值时需要使用复杂的校准和计算。

  2. 限定温度范围: 每种型号的NTC热敏电阻都有一个特定的温度工作范围,超出这个范围可能导致不准确的测量结果。

  3. 精度受限: 尽管NTC热敏电阻在一些应用中可以提供足够的精度,但在需要高精度测量的情况下,可能需要额外的校准和补偿。

  4. 阻值漂移: 随着时间的推移,NTC热敏电阻的阻值可能会发生漂移,导致测量不准确。

NTC热敏电阻在许多温度测量和控制应用中表现良好,尤其是在相对较低成本和对实时响应的需求方面。然而,在一些高精度和广泛温度范围的应用中,可能需要更复杂的传感器或补偿方法

1. 检测方法(ADC分压检测)

要测试NTC(负温度系数)热敏电阻的温度,可以使用单片机的ADC(模数转换器)来测量电阻值,并将其转换为温度值。下面是一个基本的步骤指南,用于在单片机上进行NTC热敏电阻的温度测量:

  1. 选择合适的NTC热敏电阻:选择一个与你应用要求匹配的NTC热敏电阻。不同的电阻会在不同温度下呈现不同的电阻值变化。

  2. 电路连接:将NTC热敏电阻与电路连接。通常,你会将NTC连接成一个电阻分压网络,以便将电压转换为适合ADC测量范围的电压值。

  3. 连接到单片机:将电压分压网络的输出连接到单片机的ADC引脚上。确保你已经配置了正确的引脚作为ADC输入。

  4. 编程设置:使用单片机的编程环境(比如C语言或Arduino)来配置ADC并进行测量。

1.1 搭建分压电路

下面以STM32F103C8T6作为硬件条件

在上述电路图中,在ADC分压检测线路中并联一个100nf的电容可以起到稳定检测的作用。

1.2 代码编写 (HAL库)

配置好ADC的引脚后再main方法进行开启ADC校准

HAL_ADCEx_Calibration_Start(&hadc1);

定义检测工具头文件


#ifndef CCY_PTCHOT_NTC_UTIL_H
#define CCY_PTCHOT_NTC_UTIL_H

#include "main.h"

#define NTC_DEBUG 0

/**
 * 读取NTC的检测温度值
 * @return
 */
u16 ntc_read_temp(void);

#endif //CCY_PTCHOT_NTC_UTIL_H

我们使用查表法去实现温度的检测

由硬件可以知道:通过串联分压测量R88的电压就是温感电压:当前温度的电压分度 = 中心值/(中心值+串联电阻)*3300mv*(4096/3300mv)。

其中3300mv是你的电路中的电压值3.3V。

使用查表法,并且数据用表先处理好。1、可以减少ARM的运算量,提高实时效率。2、设计工程比较大,可以节省单片机内存。因为NTC本身是热敏电阻电阻误差大,所以温度误差控制在1摄氏度比较准确。

下面是我的代码中已经计算好的ADC值表

//
// Created by Chenzedeng on 2023/8/3.
//
#include "ntc_util.h"

const u16 temp_tables[301] = {
        3974,
        3968,
        3962,
        3955,
        3948,
        3941,
        3934,
        3926,
        3918,
        3909,
        3901,
        3892,
        3882,
        3872,
        3862,
        3852,
        3841,
        3829,
        3818,
        3806,
        3793,
        3780,
        3767,
        3753,
        3738,
        3724,
        3708,
        3693,
        3677,
        3660,
        3643,
        3625,
        3607,
        3589,
        3570,
        3550,
        3530,
        3510,
        3489,
        3467,
        3445,
        3423,
        3400,
        3376,
        3352,
        3328,
        3303,
        3278,
        3252,
        3226,
        3200,
        3173,
        3145,
        3117,
        3089,
        3061,
        3032,
        3002,
        2973,
        2943,
        2912,
        2882,
        2851,
        2820,
        2788,
        2756,
        2724,
        2692,
        2660,
        2627,
        2595,
        2562,
        2529,
        2496,
        2463,
        2430,
        2396,
        2363,
        2330,
        2296,
        2263,
        2230,
        2196,
        2163,
        2130,
        2097,
        2064,
        2030,
        1997,
        1965,
        1932,
        1900,
        1867,
        1836,
        1804,
        1773,
        1742,
        1711,
        1681,
        1651,
        1621,
        1592,
        1563,
        1534,
        1506,
        1478,
        1451,
        1424,
        1397,
        1371,
        1345,
        1319,
        1294,
        1269,
        1245,
        1221,
        1197,
        1174,
        1151,
        1129,
        1107,
        1085,
        1063,
        1042,
        1021,
        1001,
        980,
        959,
        939,
        919,
        899,
        880,
        861,
        842,
        824,
        806,
        789,
        772,
        756,
        740,
        724,
        708,
        693,
        678,
        664,
        650,
        636,
        623,
        610,
        597,
        585,
        572,
        561,
        549,
        538,
        527,
        516,
        506,
        495,
        485,
        476,
        466,
        457,
        448,
        439,
        430,
        422,
        413,
        405,
        397,
        390,
        382,
        375,
        367,
        360,
        353,
        346,
        339,
        332,
        325,
        318,
        312,
        305,
        299,
        293,
        287,
        281,
        276,
        270,
        265,
        260,
        255,
        250,
        245,
        240,
        235,
        231,
        227,
        222,
        218,
        214,
        210,
        206,
        203,
        199,
        195,
        192,
        189,
        185,
        182,
        179,
        176,
        173,
        170,
        167,
        164,
        161,
        159,
        156,
        153,
        151,
        148,
        146,
        143,
        141,
        139,
        136,
        134,
        131,
        129,
        127,
        124,
        122,
        120,
        118,
        116,
        114,
        112,
        110,
        108,
        106,
        104,
        103,
        101,
        99,
        97,
        96,
        94,
        93,
        91,
        90,
        88,
        87,
        85,
        84,
        83,
        81,
        80,
        79,
        77,
        76,
        75,
        74,
        73,
        71,
        70,
        69,
        68,
        67,
        66,
        65,
        64,
        63,
        62,
        61,
        60,
        59,
        59,
        58,
        57,
        56,
        55,
        54,
        54,
        53,
        52,
        51,
        50,
        50,
        49,
        48,
        48,
        47,
        46,
        45,
        45,
        44,
        43,
        43,
        42,
        41
};

逻辑说明

  1. 获取采集到的ADC数值

  2. 将数值进行循环比对,找到第一个比它大的将结束

  3. 获取当前结束条件数值的上一个数组(i-1)的值

  4. 将本次i的值和上一个i-1的值计算差值/2

  5. 将i-1的值加上差值/2的结果去比对是否比adc数值大

  6. 如果i-1的计算结果比adc大那么认为是在左边部分就是i-1的温度值

  7. 注意温度值即就是i这个下标

//
// Created by 83503 on 2023/8/4.
//
#include "ntc_util.h"
#include "adc.h"

#define TEMP_LEN 301
#define REFERENCE_VOLTAGE 2.89
u32 adc_val;
extern const u16 temp_tables[301];

u16 ntc_read_temp(void) {
    //MF58单端玻封(25℃)NTC,B值 :3950,阻值:100K,温度范围:-40℃~+300℃
    HAL_ADC_Start(&hadc1);//启动ADC装换
    HAL_ADC_PollForConversion(&hadc1, 5);//等待转换完成,第二个参数表示超时时间,单位ms.
    if (HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC)) {
        adc_val = HAL_ADC_GetValue(&hadc1);//读取ADC转换数据,数据为12位
        double voltage = (adc_val * REFERENCE_VOLTAGE) / 4096.0;
        //计算温度
        u16 temp = 0;
        for (u16 i = 0; i < TEMP_LEN; i++) {
            if (temp_tables[i] < adc_val) {
                //如果发现首个比读取的值要大的就代表找到参考值了
                //1. 计算上一个值和当前值的差值/2
                u16 diff = (temp_tables[i - 1] - temp_tables[i]) / 2;
                if ((temp_tables[i - 1] + diff) > adc_val) {
                    temp = i - 1;
                    break;
                } else {
                    temp = i;
                    break;
                }
            }
        }
#if NTC_DEBUG == 1
        printf("电压:%lfV\tADC值:%ld\t", voltage, adc_val);
        printf("计算的温度: %d\n", temp);
#endif
        return temp;
    }
    return -1;
}

上面ntc_read_temp(void) 的方法调用将直接返回计算后的温度值。

0

评论区