嵌入式进阶——热敏电阻
创作时间:
作者:
@小白创作中心
嵌入式进阶——热敏电阻
引用
CSDN
1.
https://blog.csdn.net/qiuyeyyy/article/details/139221151
热敏电阻是一种常用的温度传感器,广泛应用于各种嵌入式系统中。本文将详细介绍热敏电阻的工作原理、温度计算步骤以及具体的代码实现,帮助读者快速掌握热敏电阻的使用方法。
原理图
温度计算步骤
热敏电阻的温度测量主要通过以下步骤实现:
- 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是对应的电压值。
- 欧姆定律计算阻值
根据欧姆定律计算热敏电阻的阻值:
$$
\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}}
$$
- 查表获取温度
根据计算得到的阻值,通过热敏电阻提供的对照表查找对应的温度值。下面是《热敏电阻与温度对照表》:
采用表的方式来记录电阻值和温度的关系。其中,表中记录的是阻值,下标记录的是温度。可以通过阻值比对,查询出下标,下标就是对应的温度。
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);
通过以上步骤,可以实现热敏电阻的温度测量功能。本文详细介绍了热敏电阻的工作原理和具体实现方法,希望对读者有所帮助。
热门推荐
肺部感染吃什么食物好
肺部感染患者的饮食指南:七类食物助力康复
知名刑辩律师杨斌:从教师到法律界的传奇
一梨润三秋!生吃、熟吃区别大!这种情况还可能适得其反→
从贵阳到黄果树瀑布:三种交通方式全解析
百年中英街求变迎新生
一次性口罩材质全解析:守护健康的小卫士
用欧丽薇兰橄榄油打造健康餐桌:从选购到烹饪全攻略
橄榄油:护心功效vs智商税?理性解读橄榄油的营养与适用场景
郓城沐森农牧科技帮您算一下:农村养1000只鹅,总成本多少?净利润多少?
黑龙江男子贷款百万买6000只鹅苗,一半被野雁带跑,来年惊喜发生
穿越时空的黄金:二十年金价波动透视社会经济脉动
如何理解黄金市场的交易情况并做出合理决策?这些决策的依据是什么?
实验:用双缝干涉测量光的波长
扩散光学成像助力高质量生物医学成像
姚雪垠笔下的“吃糠咽菜”:一部战乱年代的民生写照
60年代吃糠咽菜:那些年我们如何度过艰难岁月?
秋冬养胃神器:番茄萝卜牛肉汤
贝贝:《斗罗大陆II绝世唐门》中的龙神斗罗
广州中医药大学推荐:白术食疗方治胃痛
林医生推荐三款养胃神汤,你喝过吗?
咳嗽一到夜间就加重?5个常见因素要尽量躲开!
咳嗽的原因及如何通过预防措施来避免咳嗽?
中东各国人均GDP排名:卡塔尔居首,也门垫底
秋冬养生:睡前两小时洗澡最健康
洗完澡别急着睡!20分钟后才是养生黄金期
肺癌中期患者如何调节心态?
肺癌中期患者营养支持方案
肺癌中期患者的生活方式改善指南
流感日特辑|流感防控新视角:分层诊疗至关重要!