STM32F1与STM32CubeIDE编程实例-热敏传感器驱动

热敏传感器驱动

热敏电阻是可变电阻器,其电阻随温度变化。 它们根据其电阻对温度变化的反应方式进行分类。 在负温度系数 (NTC) 热敏电阻中,电阻随着温度的升高而降低。 在正温度系数 (PTC) 热敏电阻中,电阻随着温度的升高而增加。

导电材料包含允许电流流过的电荷载流子。 高温导致半导体材料释放更多的电荷载流子。 在由氧化铁制成的 NTC 热敏电阻中,电子是电荷载体。 在氧化镍 NTC 热敏电阻中,电荷载流子是电子空穴。

在这里插入图片描述

由于热敏电阻是可变电阻器,因此我们需要先测量电阻,然后才能计算温度。 但是,STM32 不能直接测量电阻,它只能测量电压。

STM32将测量热敏电阻和已知电阻之间某个点的电压。 这被称为分压器。 分压器的公式为:

在这里插入图片描述

其中:

  • V

o

u

t

V_{out}

Vout​为热敏电阻和已知电阻之间的电压

  • V

i

n

V_{in}

Vin​为输入电压,例如:5v

  • R1:已知电阻值
  • R2:热敏电阻的阻值

将方程简化为:

在这里插入图片描述

最后,使用 Steinhart-Hart 方程将热敏电阻的电阻转换为温度读数。

1、热敏传感器配置

开发环境搭建、系统时钟配置、调试配置及串口配置,请参考:

传感器配置如下:

在这里插入图片描述

本次实例使用轮询方式对LDR传感器进行采样。关于ADC相关介绍,请参考:

2、热敏传感器驱动实现

1)基本定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/\*
\* thermistor\_sensor.h
\*
\* Created on: Apr 24, 2022
\* Author: jenson
\*/

#ifndef \_\_THERMISTOR\_SENSOR\_H\_\_
#define \_\_THERMISTOR\_SENSOR\_H\_\_

#include <stdio.h>
#include <stm32f1xx\_hal.h>
#include "main.h"

// Steinhart-Hart方程常量
#define C1 1.009249522e-03
#define C2 2.378405444e-04
#define C3 2.019202697e-07

typedef struct {
uint16\_t id;
GPIO_TypeDef \*GPIOx; // 总线端口
uint16\_t GPIO_Pin; // 总线引脚
ADC_HandleTypeDef\* adc;
float last_value_f; // 华氏温度
float last_value_c; // 摄氏温度
float Vin; // 输入电压
float Vo; // 采样输出电压
float R1; // 已知电阻值
float R2; // 热敏电阻的阻值
}thermistor\_sensor\_t;

/\*\*\*
\* @brief 热敏电阻传感器初始化
\* @param sensor 传感器对象
\* @return 初始化成功返回1;否则,返回0
\*/
HAL_StatusTypeDef thermistor\_sensor\_init(thermistor\_sensor\_t\* sensor);

/\*\*\*
\* @brief 温度采样
\* @param sensor 传感器
\* @return 采样成功,返回1;否则返回0;采样结果储存在sensor的last\_value中。
\*/
uint8\_t thermistor\_sensor\_read(thermistor\_sensor\_t\* sensor);

#endif /\* \_\_THERMISTOR\_SENSOR\_H\_\_ \*/


2)驱动功能实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/\*
\* thermistor\_sensor.c
\*
\* Created on: Apr 24, 2022
\* Author: jenson
\*/

#include "thermistor\_sensor.h"
#include <math.h>

HAL_StatusTypeDef thermistor\_sensor\_init(thermistor\_sensor\_t \*sensor) {
// 校准ADC
HAL_StatusTypeDef status = HAL\_ADCEx\_Calibration\_Start(sensor->adc);
return status;
}

uint8\_t thermistor\_sensor\_read(thermistor\_sensor\_t \*sensor) {
// 开始采样
HAL\_ADC\_Start(sensor->adc);
// 轮询方式转换采样值
HAL\_ADC\_PollForConversion(sensor->adc, 1);
// 获取最终采样值
sensor->Vo = HAL\_ADC\_GetValue(sensor->adc);
//printf("vo = %f\r\n",sensor->Vo);
sensor->R2 = sensor->R1 \* (4096.0 / (float) sensor->Vo - 1.0);
//printf("R2 = %f\r\n",sensor->R2);
float logR2 = log(sensor->R2);
//printf("logR2 = %f\r\n",logR2);
// Steinhart-Hart方程计算温度值
float T = (1.0 / (C1 + C2 \* logR2 + C3 \* logR2 \* logR2 \* logR2));
T = T - 273.15;
sensor->last_value_c = T;
sensor->last_value_f = (T \* 9.0) / 5.0 + 32.0;

return 1;
}

3)主程序

main.c文件中添加如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/\* Private includes ----------------------------------------------------------\*/
/\* USER CODE BEGIN Includes \*/
#include "thermistor\_sensor/thermistor\_sensor.h"
/\* USER CODE END Includes \*/

/\* Private variables ---------------------------------------------------------\*/

/\* USER CODE BEGIN PV \*/
thermistor\_sensor\_t sensor;
/\* USER CODE END PV \*/

int main(void) {
/\* USER CODE BEGIN 1 \*/

/\* USER CODE END 1 \*/

/\* MCU Configuration--------------------------------------------------------\*/

/\* Reset of all peripherals, Initializes the Flash interface and the Systick. \*/
HAL\_Init();

/\* USER CODE BEGIN Init \*/

/\* USER CODE END Init \*/

/\* Configure the system clock \*/
SystemClock\_Config();

/\* USER CODE BEGIN SysInit \*/

/\* USER CODE END SysInit \*/

/\* Initialize all configured peripherals \*/
MX\_GPIO\_Init();
MX\_ADC1\_Init();
MX\_USART1\_UART\_Init();
/\* USER CODE BEGIN 2 \*/
sensor.GPIO_Pin = THERMISTOR_SENSOR_Pin;
sensor.GPIOx = THERMISTOR_SENSOR_GPIO_Port;
sensor.adc = &hadc1;
sensor.Vin = 3.3; // 3.3V输入电压
sensor.R1 = 10000; // 10K电阻
sensor.last_value_c = 0.0;
sensor.last_value_f = 32.0;
thermistor\_sensor\_init(&sensor);
printf("\*\*\*\*STM32CubeIDE:Thermistor Sensor\*\*\*\*\r\n");
/\* USER CODE END 2 \*/

/\* Infinite loop \*/
/\* USER CODE BEGIN WHILE \*/
while (1) {
/\* USER CODE END WHILE \*/

/\* USER CODE BEGIN 3 \*/
thermistor\_sensor\_read(&sensor);
printf("sensor read temperature:%f \*C\r\n",sensor.last_value_c);
printf("sensor read temperature:%f F\r\n",sensor.last_value_f);

HAL\_Delay(500);
}
/\* USER CODE END 3 \*/
}


注意:传感的R1值和输入电压需要按照实际硬件设计值

运行结果如下:

在这里插入图片描述

文章来源: https://iotsmart.blog.csdn.net/article/details/125464784