问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

嵌入式进阶——热敏电阻

创作时间:
作者:
@小白创作中心

嵌入式进阶——热敏电阻

引用
CSDN
1.
https://blog.csdn.net/qiuyeyyy/article/details/139221151

热敏电阻是一种常用的温度传感器,广泛应用于各种嵌入式系统中。本文将详细介绍热敏电阻的工作原理、温度计算步骤以及具体的代码实现,帮助读者快速掌握热敏电阻的使用方法。

原理图

温度计算步骤

热敏电阻的温度测量主要通过以下步骤实现:

  1. ADC采样计算电压

通过ADC采样获取热敏电阻位置的电压值:

$$
\frac{V_{ntc}}{2.5} = \frac{ADC_Value}{4096}
$$

$$
V_{ntc} = 2.5 \times \frac{ADC_Value}{4096}
$$

其中,ADC_Value是通过ADC采样得到的数值,范围是0-4096;V_ntc是对应的电压值。

  1. 欧姆定律计算阻值

根据欧姆定律计算热敏电阻的阻值:

$$
\frac{V_{ntc}}{R_{ntc}} = \frac{3.3V-V_{ntc}}{R_{10K}} = \frac{3.3V}{R_{10K} + R_{ntc}}
$$

通过串联分压和电流不变的原理,可以推导出热敏电阻的阻值计算公式:

$$
R_{ntc} = \frac{V_{ntc} \cdot R_{10k}}{3.3V-V_{ntc}}
$$

  1. 查表获取温度

根据计算得到的阻值,通过热敏电阻提供的对照表查找对应的温度值。下面是《热敏电阻与温度对照表》:


采用表的方式来记录电阻值和温度的关系。其中,表中记录的是阻值,下标记录的是温度。可以通过阻值比对,查询出下标,下标就是对应的温度。

u16 code temp_table[]= {
    58354, // -55
    55464, // -54
    52698, // -53
    50048, // -52
    47515, // -51
    45097, // -50
    42789, // -49
    40589, // -48
    38492, // -47
    36496, // -46
    34597, // -45
    32791, // -44
    31075, // -43
    29444, // -42
    27896, // -41
    26427, // -40
    25034, // -39
    23713, // -38
    22460, // -37
    21273, // -36
    20148, // -35
    19083, // -34
    18075, // -33
    17120, // -32
    16216, // -31
    15361, // -30
    14551, // -29
    13785, // -28
    13061, // -27
    12376, // -26
    11728, // -25
    11114, // -24
    10535, // -23
    9986,  // -22
    9468,  // -21
    8977,  // -20
    8513,  // -19
    8075,  // -18
    7660,  // -17
    7267,  // -16
    6896,  // -15
    6545,  // -14
    6212,  // -13
    5898,  // -12
    5601,  // -11
    5319,  // -10
    5053,  // -9
    4801,  // -8
    4562,  // -7
    4336,  // -6
    4122,  // -5
    3920,  // -4
    3728,  // -3
    3546,  // -2
    3374,  // -1
    3211,  // 0
    3057,  // 1
    2910,  // 2
    2771,  // 3
    2639,  // 4
    2515,  // 5
    2396,  // 6
    2284,  // 7
    2177,  // 8
    2076,  // 9
    1978,  // 10
    1889,  // 11
    1802,  // 12
    1720,  // 13
    1642,  // 14
    1568,  // 15
    1497,  // 16
    1430,  // 17
    1366,  // 18
    1306,  // 19
    1248,  // 20
    1193,  // 21
    1141,  // 22
    1092,  // 23
    1044,  // 24
    1000,  // 25
    957,   // 26
    916,   // 27
    877,   // 28
    840,   // 29
    805,   // 30
    771,   // 31
    739,   // 32
    709,   // 33
    679,   // 34
    652,   // 35
    625,   // 36
    600,   // 37
    576,   // 38
    552,   // 39
    530,   // 40
    509,   // 41
    489,   // 42
    470,   // 43
    452,   // 44
    434,   // 45
    417,   // 46
    401,   // 47
    386,   // 48
    371,   // 49
    358,   // 50
    344,   // 51
    331,   // 52
    318,   // 53
    306,   // 54
    295,   // 55
    284,   // 56
    274,   // 57
    264,   // 58
    254,   // 59
    245,   // 60
    236,   // 61
    228,   // 62
    220,   // 63
    212,   // 64
    205,   // 65
    198,   // 66
    191,   // 67
    184,   // 68
    178,   // 69
    172,   // 70
    166,   // 71
    155,   // 72
    150,   // 73
    145,   // 74
    140,   // 75
    135,   // 76
    131,   // 77
    126,   // 78
    122,   // 79
    118,   // 80
    115,   // 81
    111,   // 82
    107,   // 83
    104,   // 84
    101,   // 85
    97,    // 86
    94,    // 87
    91,    // 88
    89,    // 89
    86,    // 90
    83,    // 91
    81,    // 92
    78,    // 93
    76,    // 94
    74,    // 95
    71,    // 96
    69,    // 97
    67,    // 98
    65,    // 99
    63,    // 100
    61,    // 101
    60,    // 102
    58,    // 103
    56,    // 104
    55,    // 105
    53,    // 106
    52,    // 107
    50,    // 108
    49,    // 109
    47,    // 110
    46,    // 111
    45,    // 112
    43,    // 113
    42,    // 114
    41,    // 115
    40,    // 116
    39,    // 117
    38,    // 118
    37,    // 119
    36,    // 120
    35,    // 121
    34,    // 122
    33,    // 123
    32,    // 124
    31,    // 125
};

代码参考

创建NTC.h文件,写入以下内容:

#ifndef __NTC_H__
#define __NTC_H__
#include "Config.h"
// 求绝对值
#define abs(x)	((x > 0) ? (x) : (-(x)))
#define NTC_GPIO			GPIO_P0
#define NTC_GPIO_PIN	GPIO_Pin_4
#define NTC_ACD_CH		ADC_CH12
// 初始化NTC
void NTC_init();
// 获取温度值
int NTC_get_temperature();
#endif

创建NTC.c文件,写入以下内容(请自行将temp_table拷贝进来):

#include "NTC.h"
#include "GPIO.h"
#include "ADC.h"
#include "NVIC.h"
#include <stdio.h>
static void GPIO_config(void) {
    GPIO_InitTypeDef	GPIO_InitStructure;		//结构定义
    GPIO_InitStructure.Pin  = NTC_GPIO_PIN;		//指定要初始化的IO,
    GPIO_InitStructure.Mode = GPIO_HighZ;	//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
    GPIO_Inilize(NTC_GPIO, &GPIO_InitStructure);//初始化
}
/******************* AD配置函数 *******************/
void	ADC_config(void)
{
    ADC_InitTypeDef		ADC_InitStructure;		//结构定义
    ADC_InitStructure.ADC_SMPduty   = 31;		//ADC 模拟信号采样时间控制, 0~31(注意: SMPDUTY 一定不能设置小于 10)
    ADC_InitStructure.ADC_CsSetup   = 0;		//ADC 通道选择时间控制 0(默认),1
    ADC_InitStructure.ADC_CsHold    = 1;		//ADC 通道选择保持时间控制 0,1(默认),2,3
    ADC_InitStructure.ADC_Speed     = ADC_SPEED_2X1T;		//设置 ADC 工作时钟频率	ADC_SPEED_2X1T~ADC_SPEED_2X16T
    ADC_InitStructure.ADC_AdjResult = ADC_RIGHT_JUSTIFIED;	//ADC结果调整,	ADC_LEFT_JUSTIFIED,ADC_RIGHT_JUSTIFIED
    ADC_Inilize(&ADC_InitStructure);		//初始化
    ADC_PowerControl(ENABLE);				//ADC电源开关, ENABLE或DISABLE
    NVIC_ADC_Init(DISABLE,Priority_0);		//中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
}
// 初始化NTC
void NTC_init() {
    GPIO_config();
    ADC_config();
}
static int search_temp(float rst_Rx10){
    int i, min_index = 0;
    // 计算数组长度
    int len = sizeof(temp_table) / sizeof(u16);
    
    // 记录最小差值 
    float min_diff = abs(rst_Rx10 - temp_table[0]);
    
    for (i = 1; i < len; i++){
        // 计算数组里每一个阻值和rst_Rx10的差值
        float diff = abs(rst_Rx10 - temp_table[i]);
        
        // 得到差值最小元素对应的索引i
        if(diff < min_diff){
            // 如果有更小的差值,赋值
            min_diff = diff;
            min_index = i;
        }
    }
    
    printf("len: %d R: %.2f min_diff: %.2f min_index: %d \n", len, rst_Rx10, min_diff, min_index);
    
    return min_index;
}
// 获取温度值
int NTC_get_temperature() {
    u16 adc_value;
    float rst_V;
    float rst_R;
    int rst_T;
    // 获取对应的ADC值
    adc_value = Get_ADCResult(NTC_ACD_CH);
    // adc_value返回的值范围 0 -> 4096
    // 等同于P05引脚的电压值和Vref的占比  1024
    // X = ADC_V  * Vref / 4096
    // 计算电压
    rst_V = adc_value * 2.5 / 4096;
    // 计算电阻值
    rst_R = rst_V * 10 / (3.3 - rst_V);
    // 9.36KΩ 将阻值兑换成温度
    rst_T = search_temp(rst_R * 100) - 55;
    printf("ADC: %d voltage: %.2f R = %.2f T = %d℃ \n", adc_value, rst_V, rst_R, (int)rst_T);
        
        return rst_T;
}

在main函数中调用:

int rst_T;
NTC_init();
rst_T = NTC_get_temperature();
printf("温度:%d \n", rst_T);

通过以上步骤,可以实现热敏电阻的温度测量功能。本文详细介绍了热敏电阻的工作原理和具体实现方法,希望对读者有所帮助。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号