手把手教你用STM32F103C8T6和NTC热敏电阻DIY一个水温监测器(附OLED显示和超温报警)
手把手教你用STM32F103C8T6和NTC热敏电阻DIY一个水温监测器附OLED显示和超温报警水温监测在家庭和工业场景中有着广泛的应用无论是鱼缸温度监控、咖啡机水温控制还是小型发酵罐的温度管理一个可靠的水温监测器都能发挥重要作用。本文将详细介绍如何利用STM32F103C8T6单片机和NTC热敏电阻从零开始打造一个功能完善的水温监测系统包含OLED实时显示和超温报警功能。这个项目特别适合电子爱好者、嵌入式系统初学者以及需要特定温度监控解决方案的DIY玩家。我们将采用低成本、易获取的元器件通过清晰的步骤讲解和完整的代码实现确保每位读者都能成功复现这个项目。1. 项目规划与元器件选型1.1 核心元器件介绍STM32F103C8T6是一款基于ARM Cortex-M3内核的32位微控制器具有丰富的外设资源包括多通道12位ADC模数转换器非常适合本项目的数据采集需求。它的主要特点包括72MHz主频性能强劲64KB Flash20KB SRAM2个12位ADC16通道丰富的GPIO接口NTC热敏电阻负温度系数热敏电阻是本项目的温度传感核心元件。我们推荐使用10KΩ25℃的NTC其特性包括参数值标称电阻10KΩ25℃B值3950K工作温度范围-40℃~125℃精度±1%1.2 辅助元器件清单除了核心元件外我们还需要以下组件0.96寸OLED显示屏I2C或SPI接口10KΩ精密电阻用于分压电路LED指示灯用于超温报警220Ω限流电阻用于LED面包板或PCB板杜邦线若干USB转TTL串口模块用于程序下载2. 硬件电路设计与搭建2.1 温度传感电路设计NTC热敏电阻的阻值会随温度变化而变化我们需要将其转换为电压信号供STM32的ADC读取。采用简单的分压电路设计3.3V ---[10KΩ固定电阻]---[NTC]---GND | ADC输入这个电路的工作原理是NTC与10KΩ固定电阻组成分压电路当温度变化时NTC阻值变化分压点电压随之变化STM32的ADC读取这个电压值通过计算转换为实际温度值2.2 硬件连接指南将各元件按照以下方式连接STM32引脚连接目标PA0NTC分压点PB6 (SCL)OLED SCLPB7 (SDA)OLED SDAPB10LED正极3.3V分压电路供电GND公共地线提示如果使用SPI接口的OLED连接方式会有所不同请参考OLED模块的说明书。3. 软件开发环境配置3.1 开发工具准备我们需要以下软件工具Keil MDK-ARMSTM32的主要开发环境STM32CubeMX图形化配置工具串口调试助手用于调试输出OLED驱动库根据使用的OLED型号选择3.2 工程创建与配置使用STM32CubeMX创建基础工程选择MCU型号STM32F103C8T6配置时钟选择内部或外部晶振启用外设ADC1通道0I2C1如果是I2C OLEDGPIO输出用于LED生成代码后在Keil中打开工程添加必要的驱动文件。4. 核心代码实现4.1 ADC初始化与数据采集首先配置ADC模块实现温度数据的采集void ADC_Init(void) { ADC_InitTypeDef ADC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; // 使能ADC和GPIO时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE); // 配置ADC输入引脚 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通道 ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5); // 使能ADC ADC_Cmd(ADC1, ENABLE); // ADC校准 ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while(ADC_GetCalibrationStatus(ADC1)); // 开始转换 ADC_SoftwareStartConvCmd(ADC1, ENABLE); } uint16_t Get_ADC_Value(void) { while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); return ADC_GetConversionValue(ADC1); }4.2 温度计算与校准NTC的温度计算通常有两种方法查表法预先测量不同温度下的ADC值建立查找表公式法使用Steinhart-Hart方程计算温度这里我们介绍查表法的实现// 温度-ADC值对应表 const uint16_t tempTable[] { // 温度(℃), ADC值 0, 4095, 10, 3500, 20, 2400, 30, 1700, 40, 1200, 50, 850, 60, 600 }; float Get_Temperature(uint16_t adcValue) { uint8_t i; float temp; // 查找最近的ADC值 for(i0; isizeof(tempTable)/sizeof(tempTable[0])-2; i2) { if(adcValue tempTable[i1]) { break; } } // 线性插值计算温度 if(i 0) { temp tempTable[i]; } else { temp tempTable[i] (float)(adcValue - tempTable[i1]) * (tempTable[i2] - tempTable[i]) / (tempTable[i3] - tempTable[i1]); } return temp; }4.3 OLED显示实现OLED显示部分需要先初始化显示屏然后定期刷新显示内容void OLED_Display(float temp, uint16_t adcValue) { char buffer[16]; OLED_Clear(); // 显示ADC值 OLED_ShowString(0, 0, ADC:); sprintf(buffer, %4d, adcValue); OLED_ShowString(40, 0, buffer); // 显示温度值 OLED_ShowString(0, 2, Temp:); sprintf(buffer, %2.1fC, temp); OLED_ShowString(40, 2, buffer); // 显示状态 if(temp 60.0) { OLED_ShowString(0, 4, Status: ALARM!); } else { OLED_ShowString(0, 4, Status: Normal); } OLED_Refresh(); }4.4 超温报警功能当检测到温度超过设定阈值时触发LED报警void Temp_Alarm(float temp) { if(temp 60.0) { // 闪烁LED GPIO_SetBits(GPIOB, GPIO_Pin_10); Delay_ms(100); GPIO_ResetBits(GPIOB, GPIO_Pin_10); Delay_ms(100); } else { // 关闭LED GPIO_ResetBits(GPIOB, GPIO_Pin_10); } }5. 系统集成与调试5.1 主程序流程将各个模块整合到主程序中int main(void) { uint16_t adcValue; float temperature; // 硬件初始化 System_Init(); ADC_Init(); OLED_Init(); LED_Init(); while(1) { // 获取ADC值 adcValue Get_ADC_Value(); // 计算温度 temperature Get_Temperature(adcValue); // 显示信息 OLED_Display(temperature, adcValue); // 温度报警 Temp_Alarm(temperature); // 延时500ms Delay_ms(500); } }5.2 常见问题排查在实际制作过程中可能会遇到以下问题ADC读数不稳定检查电源是否稳定增加软件滤波算法如滑动平均确保NTC与固定电阻接触良好温度显示不准确重新校准温度-ADC对应表检查NTC的B值参数是否正确确保NTC与水有良好的热接触OLED不显示检查I2C/SPI接线是否正确确认OLED的电源电压3.3V或5V检查初始化代码是否正确5.3 性能优化建议为了提高系统的性能和可靠性可以考虑以下优化措施软件滤波对ADC采样值进行滑动平均或中值滤波温度补偿考虑环境温度对测量的影响低功耗设计在不需要频繁测量的场合可以进入低功耗模式数据记录添加SD卡模块记录温度变化历史6. 项目扩展与应用6.1 无线传输功能通过添加ESP8266或HC-05蓝牙模块可以实现温度的无线监测WiFi传输将温度数据上传到物联网平台蓝牙传输在手机上实时查看温度无线报警当温度异常时发送手机通知6.2 多路温度监测利用STM32的多通道ADC可以同时监测多个点的温度增加NTC传感器数量修改代码支持多通道采集在OLED上轮显或多行显示6.3 温度控制功能结合继电器模块可以实现自动温度控制设置目标温度范围当温度过低时自动开启加热当温度过高时自动开启冷却7. 实际应用案例这个水温监测器可以应用于多种场景水族箱温度监控确保热带鱼的生存环境稳定咖啡机水温控制保证咖啡冲泡的最佳温度家庭酿酒监测监控发酵过程的温度变化实验室恒温水浴作为简单的温度监测装置在最近的一个实际应用中我将这个系统用于监控我的家庭水培植物的营养液温度。通过连续监测发现白天的温度波动比预期大于是增加了简单的遮阳措施显著提高了植物的生长状况。