news 2026/5/26 2:50:01

用STM32F103C8T6和10K NTC做个水温计,OLED显示还能超温报警(附完整工程)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用STM32F103C8T6和10K NTC做个水温计,OLED显示还能超温报警(附完整工程)

基于STM32F103的智能水温监测系统开发实战

水温监测在工业控制、家用电器和科研实验中都是基础但关键的功能。对于电子爱好者来说,用常见的STM32开发板和NTC热敏电阻搭建一个水温监测系统,不仅能学习嵌入式开发的完整流程,还能获得一个实用的DIY项目。本文将详细介绍如何用STM32F103C8T6(BluePill开发板)、10K NTC热敏电阻和0.96寸OLED屏,打造一个带超温报警功能的水温计。

1. 项目规划与硬件选型

水温监测系统的核心在于准确采集温度信号并将其转换为可读数据。我们选择STM32F103C8T6作为主控,不仅因为它的性价比高,更因为其内置的12位ADC能满足我们的精度要求。NTC热敏电阻是温度传感器的理想选择,特别是10KΩ @25℃的型号,因其响应快、价格低且易于获取。

关键硬件清单:

  • STM32F103C8T6最小系统板(BluePill)
  • 10K NTC热敏电阻(B值3950)
  • 0.96寸OLED显示屏(SSD1306驱动,I2C或SPI接口)
  • 10KΩ 1%精度金属膜电阻
  • LED指示灯(用于超温报警)
  • 杜邦线、面包板或PCB

提示:NTC热敏电阻的B值很重要,不同B值的电阻需要不同的温度计算公式。购买时务必确认B值参数。

硬件连接原理很简单:NTC与10K电阻串联分压,中间节点接STM32的ADC输入引脚。OLED用于显示实时温度,LED用于超温报警指示。整个系统可由USB供电或3.7V锂电池供电。

2. 电路设计与ADC配置

NTC的电阻值随温度变化是非线性的,我们需要通过分压电路将其转换为电压信号。将NTC与10K电阻串联,接在3.3V与GND之间,中间节点连接STM32的ADC输入引脚(如PA0)。

关键电路参数计算:

参数计算公式示例值(25℃)
NTC电阻R = R25×exp[B×(1/T-1/T25)]10KΩ
分压电压Vout = 3.3V × (Rntc)/(Rntc + 10K)1.65V
ADC值ADC = Vout × 4095 / 3.3约2048

STM32的ADC需要正确初始化才能获得稳定读数。以下是使用标准外设库的配置代码:

void ADC1_Init(void) { ADC_InitTypeDef ADC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; // 使能ADC1和GPIOA时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE); // 配置PA0为模拟输入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStructure); // ADC基本配置 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC1, &ADC_InitStructure); // 配置ADC通道0,采样时间239.5周期 ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5); // 使能ADC并校准 ADC_Cmd(ADC1, ENABLE); ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while(ADC_GetCalibrationStatus(ADC1)); // 启动ADC转换 ADC_SoftwareStartConvCmd(ADC1, ENABLE); }

注意:ADC采样时间需要根据信号源阻抗调整。对于NTC电路,较长的采样时间(239.5周期)有助于获得更稳定的读数。

3. 温度计算与数据拟合

NTC的电阻-温度关系遵循Steinhart-Hart方程:

1/T = 1/T0 + (1/B) × ln(R/R0)

其中T是开尔文温度,R是当前电阻值,R0是参考温度下的电阻值(如10K@25℃),B是材料常数(如3950)。

实现步骤:

  1. 读取ADC值并转换为电压
  2. 计算NTC当前电阻值
  3. 使用Steinhart-Hart方程计算温度
  4. 将开尔文温度转换为摄氏度

以下是温度计算的C语言实现:

float CalculateTemperature(uint16_t adcValue) { float voltage = adcValue * 3.3f / 4095.0f; float ntcResistance = 10000.0f * voltage / (3.3f - voltage); // 分压公式 // Steinhart-Hart方程 float steinhart; steinhart = ntcResistance / 10000.0f; // (R/R0) steinhart = log(steinhart); // ln(R/R0) steinhart /= 3950.0f; // 1/B * ln(R/R0) steinhart += 1.0f / (25.0f + 273.15f); // + (1/T0) steinhart = 1.0f / steinhart; // 倒数 steinhart -= 273.15f; // 开尔文转摄氏度 return steinhart; }

对于资源有限的MCU,可以使用查表法替代复杂的浮点运算。预先计算不同ADC值对应的温度并存储在数组中,实际运行时直接查表。

4. OLED显示与报警功能实现

SSD1306 OLED显示屏可以通过I2C或SPI接口与STM32连接。这里以I2C为例,使用现成的OLED驱动库可以大大简化开发。

显示内容设计:

  • 第一行:当前温度值(如"Temp: 25.6C")
  • 第二行:ADC原始值(如"ADC: 2048")
  • 第三行:温度状态("Normal"或"ALARM!")

报警功能通过比较当前温度与阈值(如60℃)实现。当温度超限时,LED开始闪烁,同时OLED显示报警信息。

// 报警处理函数 void HandleAlarm(float temperature) { static uint32_t lastToggle = 0; static uint8_t ledState = 0; if(temperature > 60.0f) { // 闪烁LED(每200ms切换一次状态) if(HAL_GetTick() - lastToggle > 200) { ledState = !ledState; HAL_GPIO_WritePin(GPIOB, GPIO_Pin_10, ledState ? GPIO_PIN_SET : GPIO_PIN_RESET); lastToggle = HAL_GetTick(); } // OLED显示报警 OLED_ShowString(3, 1, "ALARM! >60C"); } else { // 正常状态 HAL_GPIO_WritePin(GPIOB, GPIO_Pin_10, GPIO_PIN_RESET); OLED_ShowString(3, 1, "Normal "); } }

5. 系统优化与误差处理

在实际应用中,有几个关键点会影响测量精度:

  1. ADC参考电压:STM32内部参考电压可能有±5%的偏差,对于要求高的应用,可以使用外部精密基准源。
  2. 电阻精度:分压电阻应选用1%精度的金属膜电阻。
  3. NTC自热效应:测量电流会导致NTC轻微发热,建议使用较大的串联电阻(如10K)降低电流。
  4. 软件滤波:采用滑动平均或中值滤波算法处理ADC读数。

滑动平均滤波实现:

#define FILTER_SIZE 10 uint16_t FilterADCValue(uint16_t newValue) { static uint16_t buffer[FILTER_SIZE] = {0}; static uint8_t index = 0; static uint32_t sum = 0; // 减去最旧的值 sum -= buffer[index]; // 添加新值 sum += newValue; buffer[index] = newValue; index = (index + 1) % FILTER_SIZE; return sum / FILTER_SIZE; }

6. 项目扩展与进阶应用

基础水温监测系统完成后,可以考虑以下扩展功能:

  • 数据记录:添加SD卡模块,定期记录温度数据
  • 无线传输:通过蓝牙或WiFi模块将数据发送到手机或云端
  • PID控制:结合加热元件实现恒温控制
  • 多路监测:扩展多个NTC传感器监测不同位置水温

对于需要更高精度的应用,可以考虑:

  1. 使用铂电阻(PT100/PT1000)替代NTC
  2. 采用专用温度传感器芯片(如DS18B20)
  3. 增加温度校准功能,通过两点校准修正系统误差

一个完整的嵌入式项目开发不仅涉及硬件和代码,还需要考虑电源管理、外壳设计等实际问题。例如,如果用于鱼缸水温监测,需要考虑防水措施;如果是便携式应用,则需要优化功耗延长电池寿命。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/26 2:49:13

JMeter分布式测试实战指南

1.使用原因:如果并发数比较大的情况下,例如项目需要10000并发,单台电脑和CPU可能无法支持,这时可以使用jmeter的分布式。2.分布式原理:选择一台控制机和其他机器作为代理机。执行时,控制机会把脚本发送到每…

作者头像 李华
网站建设 2026/5/26 2:49:07

百度网盘解析工具:3分钟获取高速下载链接,告别限速烦恼

百度网盘解析工具:3分钟获取高速下载链接,告别限速烦恼 【免费下载链接】baidu-wangpan-parse 获取百度网盘分享文件的下载地址 项目地址: https://gitcode.com/gh_mirrors/ba/baidu-wangpan-parse 你是否曾经为百度网盘的龟速下载而烦恼&#xf…

作者头像 李华
网站建设 2026/5/26 2:44:34

告别4G固定时序!5G NR中PUCCH上报HARQ-ACK的灵活配置实战解析

5G NR中PUCCH HARQ-ACK反馈的灵活时序配置实战指南在无线通信技术从4G向5G演进的过程中,物理层控制信道的设计理念发生了根本性变革。作为上行控制信息(UCI)传输的核心载体,物理上行控制信道(PUCCH)在5G新空…

作者头像 李华