STM32 温度采集实战:片上传感器与外部 NTC 分压电路深度解析
👁 2 阅读 · 2026-08-19 · STM32 传感器
温度采集是嵌入式系统中最常见的任务之一。本文面向有一定基础的开发者,深入剖析 STM32 的片上温度传感器原理与校准方法,并详细讲解外部 NTC 热敏电阻分压电路的设计、计算与 ADC 采样实现。通过对比两种方案,帮助你在实际项目中做出合理选型,并附上完整的 HAL 库代码示例,助你快速落地。
## 一、为什么需要两种温度采集方案?
在 STM32 项目中,温度采集的需求无处不在:电源监控、电机保护、环境监测等。片上温度传感器(如 STM32F4 系列内置的)无需外部硬件,适合粗略的芯片温度监测;而外部 NTC 热敏电阻精度高、响应快,适合测量环境或目标物体温度。理解两者的原理与实现,是嵌入式工程师的基本功。
## 二、STM32 片上温度传感器:原理与校准
### 2.1 工作原理
STM32 内部集成了一个基于 PN 结的温度传感器,其输出电压与温度呈线性关系。该电压通过 ADC 内部通道(如 STM32F407 的 ADC1_IN16)采样,转换公式为:
```c
温度(°C) = (V_sense - V_25) / Avg_Slope + 25
```
其中 `V_25` 是 25°C 时的典型电压(通常为 0.76V),`Avg_Slope` 是平均斜率(典型值 2.5 mV/°C)。注意:这些参数因芯片型号而异,需查阅数据手册。
### 2.2 关键配置步骤
1. 使能 ADC 时钟和内部传感器电源(`LL_ADC_EnableInternalRegulator`)。
2. 配置 ADC 为单次转换模式,选择内部温度传感器通道。
3. 读取 ADC 值并转换为电压,再套用公式计算温度。
4. 为提高精度,建议使用芯片出厂校准值(如 STM32F3/F4 系列在 ROM 中存储的校准数据)。
### 2.3 代码示例(HAL 库)
```c
#include "stm32f4xx_hal.h"
ADC_HandleTypeDef hadc;
void MX_ADC1_Init(void) {
hadc.Instance = ADC1;
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.ScanConvMode = DISABLE;
hadc.Init.ContinuousConvMode = DISABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.NbrOfConversion = 1;
HAL_ADC_Init(&hadc);
}
float ReadChipTemperature(void) {
ADC_ChannelConfTypeDef sConfig = {0};
sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_84CYCLES;
HAL_ADC_ConfigChannel(&hadc, &sConfig);
HAL_ADC_Start(&hadc);
HAL_ADC_PollForConversion(&hadc, 100);
uint32_t adc_val = HAL_ADC_GetValue(&hadc);
HAL_ADC_Stop(&hadc);
float voltage = (float)adc_val * 3.3f / 4095.0f;
float temp = (voltage - 0.76f) / 0.0025f + 25.0f;
return temp;
}
```
**注意**:实际使用时,建议从芯片 ROM 读取校准值(如 `V25` 和 `Avg_Slope`),以替代上述典型值,可显著提高精度。
## 三、外部 NTC 分压电路:设计与计算
### 3.1 电路原理
NTC(负温度系数)热敏电阻的阻值随温度升高而降低。常用分压电路:将 NTC 与固定电阻串联,中间节点接 ADC 输入。选择固定电阻时,需考虑温度测量范围和灵敏度。
(示意图:VCC -> R_fixed -> 节点 -> NTC -> GND)
### 3.2 电阻选型与计算
假设 NTC 在 25°C 时阻值为 10kΩ(B=3950),电源为 3.3V,ADC 为 12 位。
- 固定电阻 R_fixed 通常取 NTC 在测量范围中值附近的阻值,例如 10kΩ,以获得最大线性度。
- 节点电压公式:`V_out = VCC * R_ntc / (R_fixed + R_ntc)`
- 温度与阻值关系(Steinhart-Hart 简化公式):
```c
float NTC_ResistanceToTemp(float resistance) {
float T0 = 298.15f; // 25°C 开尔文
float B = 3950.0f;
float R0 = 10000.0f;
float invT = 1.0f/T0 + (1.0f/B) * logf(resistance / R0);
return 1.0f / invT - 273.15f;
}
```
### 3.3 配置步骤
1. 硬件连接:NTC 一端接 3.3V,另一端接固定电阻到 GND,中间节点接 STM32 的 ADC 引脚(如 PA0)。
2. 配置 ADC 引脚为模拟输入模式。
3. 初始化 ADC,选择对应通道。
4. 读取 ADC 值,计算节点电压,反推 NTC 阻值,再转换为温度。
### 3.4 代码示例(HAL 库)
```c
#include "stm32f4xx_hal.h"
#include
ADC_HandleTypeDef hadc;
void MX_ADC1_Init(void) {
__HAL_RCC_ADC1_CLK_ENABLE();
hadc.Instance = ADC1;
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.ScanConvMode = DISABLE;
hadc.Init.ContinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.NbrOfConversion = 1;
HAL_ADC_Init(&hadc);
}
float ReadNTC_Temperature(void) {
ADC_ChannelConfTypeDef sConfig = {0};
sConfig.Channel = ADC_CHANNEL_0; // PA0
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_84CYCLES;
HAL_ADC_ConfigChannel(&hadc, &sConfig);
HAL_ADC_Start(&hadc);
HAL_ADC_PollForConversion(&hadc, 100);
uint32_t adc_val = HAL_ADC_GetValue(&hadc);
HAL_ADC_Stop(&hadc);
float voltage = (float)adc_val * 3.3f / 4095.0f;
float r_ntc = 10000.0f * voltage / (3.3f - voltage); // 假设固定电阻为10k
return NTC_ResistanceToTemp(r_ntc);
}
```
## 四、两种方案对比与选型建议
- **片上传感器**:零成本、无需外部电路,但精度低(±2°C 左右),且测量的是芯片内部温度,受负载影响大。适合用于芯片过热保护。
- **外部 NTC**:精度高(可达 ±0.5°C),响应快,可测量环境或物体温度,但需要额外电路和校准。适合对温度精度有要求的应用。
**选型建议**:若仅需监控芯片温度,优先使用片上传感器;若需测量外部环境,则选用 NTC 并做好分压电路设计。
## 五、注意事项与工程实践
- **ADC 参考电压**:确保 VREF+ 稳定,否则会影响采样精度。可使用内部参考电压(如 2.5V)并配置 ADC 为相应范围。
- **采样时间**:NTC 阻值较大时,需增加 ADC 采样时间(如 84 或 480 周期),以稳定内部电容充电。
- **滤波处理**:对 ADC 采样值进行软件滤波(如滑动平均),可减少噪声干扰。
- **校准**:NTC 的 B 值存在离散性,批量生产时建议使用标准温度源进行两点校准。
- **电源去耦**:在 NTC 分压电路附近放置 100nF 电容,抑制电源高频噪声。
## 六、总结
本文详细介绍了 STM32 片上温度传感器和外部 NTC 分压电路两种方案,从原理到代码实现,并给出了选型建议。实际项目中,应根据精度、成本和环境要求灵活选择。希望这篇文章能帮助你快速完成温度采集功能,并在嵌入式开发中少走弯路。