从零打造智能温度监测系统STM32F103C8T6与DS18B20实战指南1. 项目准备与硬件搭建在开始动手之前我们需要先了解整个系统的组成部分。这个温度监测系统主要由四大模块构成控制核心、温度采集、显示界面和报警交互。每个模块的选择都经过精心考量确保在性价比和性能之间取得平衡。物料清单BOMSTM32F103C8T6最小系统板蓝色药丸板 ×1DS18B20温度传感器防水型 ×10.96寸OLED显示屏I2C接口 ×15mm LED红/绿各一 ×2轻触按键 ×210KΩ电阻 ×2面包板及杜邦线若干硬件连接示意图如下模块STM32引脚连接说明DS18B20 DATAPA1需接4.7K上拉电阻OLED SCLPB6I2C1时钟线OLED SDAPB7I2C1数据线红色LEDPC13高温报警指示灯绿色LEDPC14低温报警指示灯设置按键PA0温区设置下降沿触发确认按键PA8参数确认下降沿触发提示DS18B20的数据线必须连接4.7KΩ上拉电阻至3.3V否则无法正常通信。若使用防水型传感器注意导线颜色定义通常红色为VCC黑色为GND黄色为DATA。2. 开发环境配置2.1 软件工具链安装工欲善其事必先利其器。我们需要准备以下开发工具STM32CubeMX图形化配置工具自动生成初始化代码Keil MDK-ARM专业嵌入式开发IDE社区版即可ST-Link驱动下载调试工具链串口调试助手用于调试信息输出安装完成后按以下步骤创建工程# 创建项目目录结构 mkdir temp_monitor cd temp_monitor mkdir -p Drivers/STM32F1xx_HAL_Driver mkdir -p Middlewares/Third_Party2.2 CubeMX工程配置启动CubeMX按步骤配置选择MCU型号STM32F103C8T6系统核心配置SYS: Debug选择Serial WireRCC: HSE选择Crystal/Ceramic Resonator时钟树设置HCLK设置为72MHz8MHz晶振×9倍频引脚分配PA1: GPIO_OutputDS18B20数据线PB6/PB7: I2C1_SCL/I2C1_SDAPC13/PC14: GPIO_OutputPA0/PA8: GPIO_EXTI配置完成后生成代码选择MDK-ARM工具链。3. 传感器驱动开发3.1 DS18B20单总线协议实现DS18B20采用独特的单总线协议需要精确的时序控制。以下是关键操作函数// 单总线复位脉冲 void DS18B20_Reset(void) { HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_RESET); delay_us(480); HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_SET); delay_us(60); while(!HAL_GPIO_ReadPin(DS18B20_PORT, DS18B20_PIN)); delay_us(480); } // 写入一个字节 void DS18B20_WriteByte(uint8_t data) { for(int i0; i8; i) { HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_RESET); delay_us(2); HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, (datai)0x01); delay_us(60); HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_SET); } } // 读取温度值 float DS18B20_ReadTemp(void) { uint8_t tempL, tempH; DS18B20_Reset(); DS18B20_WriteByte(0xCC); // 跳过ROM DS18B20_WriteByte(0x44); // 启动温度转换 delay_ms(750); // 等待转换完成 DS18B20_Reset(); DS18B20_WriteByte(0xCC); DS18B20_WriteByte(0xBE); // 读取暂存器 tempL DS18B20_ReadByte(); tempH DS18B20_ReadByte(); return ((tempH8)|tempL) * 0.0625; }注意时序控制必须精确到微秒级建议使用STM32的硬件定时器实现delay_us函数。3.2 温度校准与滤波为提高测量精度我们需要对原始数据进行处理多点校准在已知温度点如冰水混合物0℃、沸水100℃记录传感器读数滑动平均滤波减少随机误差#define FILTER_LEN 5 float temp_history[FILTER_LEN]; uint8_t filter_idx 0; float get_filtered_temp(void) { float sum 0; temp_history[filter_idx] DS18B20_ReadTemp(); filter_idx (filter_idx 1) % FILTER_LEN; for(int i0; iFILTER_LEN; i) { sum temp_history[i]; } return sum / FILTER_LEN; }4. 用户界面实现4.1 OLED显示驱动我们使用SSD1306驱动的OLED屏通过I2C接口通信。首先移植OLED驱动库在CubeMX中启用I2C1速度设为400kHz添加SSD1306驱动文件到项目实现基础显示函数// OLED初始化 void OLED_Init(void) { OLED_WR_Byte(0xAE, OLED_CMD); // 关闭显示 OLED_WR_Byte(0xD5, OLED_CMD); // 设置时钟分频 OLED_WR_Byte(0x80, OLED_CMD); // ... 其他初始化命令 OLED_WR_Byte(0xAF, OLED_CMD); // 开启显示 } // 显示温度界面 void show_temp_screen(float temp) { OLED_Clear(); OLED_ShowString(0, 0, Temp Monitor, 16); OLED_ShowString(0, 2, Current:, 16); OLED_ShowNum(72, 2, (int)temp, 3, 16); OLED_ShowString(108, 2, C, 16); OLED_ShowString(0, 4, Set Range:, 16); OLED_ShowNum(72, 4, temp_low, 2, 16); OLED_ShowString(96, 4, -, 16); OLED_ShowNum(108, 4, temp_high, 2, 16); }4.2 报警功能实现温度报警功能通过LED和蜂鸣器可选实现void check_temp_alarm(float temp) { static uint8_t alarm_state 0; if(temp temp_high) { HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_SET); alarm_state 1; } else if(temp temp_low) { HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_SET); alarm_state 1; } else if(alarm_state) { HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_RESET); alarm_state 0; } }5. 系统整合与优化5.1 主程序逻辑设计系统采用状态机架构确保各功能模块协调工作typedef enum { STATE_NORMAL, STATE_SET_LOW, STATE_SET_HIGH } SystemState; void main(void) { SystemState state STATE_NORMAL; float current_temp; HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_I2C1_Init(); OLED_Init(); DS18B20_Init(); while(1) { current_temp get_filtered_temp(); switch(state) { case STATE_NORMAL: show_temp_screen(current_temp); check_temp_alarm(current_temp); break; case STATE_SET_LOW: // 温区设置逻辑 break; case STATE_SET_HIGH: // 温区设置逻辑 break; } HAL_Delay(1000); } }5.2 功耗优化技巧对于电池供电的应用可采取以下措施降低功耗传感器间歇工作每10秒唤醒一次DS18B20OLED局部刷新只更新变化的部分区域低功耗模式在空闲时进入STOP模式void enter_low_power_mode(void) { HAL_SuspendTick(); HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); SystemClock_Config(); // 唤醒后重新配置时钟 HAL_ResumeTick(); }6. 进阶功能扩展完成基础功能后可以考虑添加以下增强特性历史数据记录利用STM32内部Flash储温度日志蓝牙传输通过HC-05模块将数据发送到手机多传感器网络并联多个DS18B20实现区域监测Web界面通过ESP8266实现远程监控// 多传感器读取示例 void read_multiple_sensors(void) { DS18B20_Reset(); DS18B20_WriteByte(0x55); // 匹配ROM命令 DS18B20_WriteROM(rom_code); // 发送特定传感器ROM码 DS18B20_WriteByte(0x44); // 启动转换 }在实际项目中我发现DS18B20的防水型号特别适合户外应用但要注意导线接头处的密封处理。对于需要快速响应的场景可以将采样间隔缩短到500ms同时适当减少滤波窗口大小。
手把手教你用STM32F103C8T6和DS18B20做个OLED温度计(附报警功能)
从零打造智能温度监测系统STM32F103C8T6与DS18B20实战指南1. 项目准备与硬件搭建在开始动手之前我们需要先了解整个系统的组成部分。这个温度监测系统主要由四大模块构成控制核心、温度采集、显示界面和报警交互。每个模块的选择都经过精心考量确保在性价比和性能之间取得平衡。物料清单BOMSTM32F103C8T6最小系统板蓝色药丸板 ×1DS18B20温度传感器防水型 ×10.96寸OLED显示屏I2C接口 ×15mm LED红/绿各一 ×2轻触按键 ×210KΩ电阻 ×2面包板及杜邦线若干硬件连接示意图如下模块STM32引脚连接说明DS18B20 DATAPA1需接4.7K上拉电阻OLED SCLPB6I2C1时钟线OLED SDAPB7I2C1数据线红色LEDPC13高温报警指示灯绿色LEDPC14低温报警指示灯设置按键PA0温区设置下降沿触发确认按键PA8参数确认下降沿触发提示DS18B20的数据线必须连接4.7KΩ上拉电阻至3.3V否则无法正常通信。若使用防水型传感器注意导线颜色定义通常红色为VCC黑色为GND黄色为DATA。2. 开发环境配置2.1 软件工具链安装工欲善其事必先利其器。我们需要准备以下开发工具STM32CubeMX图形化配置工具自动生成初始化代码Keil MDK-ARM专业嵌入式开发IDE社区版即可ST-Link驱动下载调试工具链串口调试助手用于调试信息输出安装完成后按以下步骤创建工程# 创建项目目录结构 mkdir temp_monitor cd temp_monitor mkdir -p Drivers/STM32F1xx_HAL_Driver mkdir -p Middlewares/Third_Party2.2 CubeMX工程配置启动CubeMX按步骤配置选择MCU型号STM32F103C8T6系统核心配置SYS: Debug选择Serial WireRCC: HSE选择Crystal/Ceramic Resonator时钟树设置HCLK设置为72MHz8MHz晶振×9倍频引脚分配PA1: GPIO_OutputDS18B20数据线PB6/PB7: I2C1_SCL/I2C1_SDAPC13/PC14: GPIO_OutputPA0/PA8: GPIO_EXTI配置完成后生成代码选择MDK-ARM工具链。3. 传感器驱动开发3.1 DS18B20单总线协议实现DS18B20采用独特的单总线协议需要精确的时序控制。以下是关键操作函数// 单总线复位脉冲 void DS18B20_Reset(void) { HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_RESET); delay_us(480); HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_SET); delay_us(60); while(!HAL_GPIO_ReadPin(DS18B20_PORT, DS18B20_PIN)); delay_us(480); } // 写入一个字节 void DS18B20_WriteByte(uint8_t data) { for(int i0; i8; i) { HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_RESET); delay_us(2); HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, (datai)0x01); delay_us(60); HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_SET); } } // 读取温度值 float DS18B20_ReadTemp(void) { uint8_t tempL, tempH; DS18B20_Reset(); DS18B20_WriteByte(0xCC); // 跳过ROM DS18B20_WriteByte(0x44); // 启动温度转换 delay_ms(750); // 等待转换完成 DS18B20_Reset(); DS18B20_WriteByte(0xCC); DS18B20_WriteByte(0xBE); // 读取暂存器 tempL DS18B20_ReadByte(); tempH DS18B20_ReadByte(); return ((tempH8)|tempL) * 0.0625; }注意时序控制必须精确到微秒级建议使用STM32的硬件定时器实现delay_us函数。3.2 温度校准与滤波为提高测量精度我们需要对原始数据进行处理多点校准在已知温度点如冰水混合物0℃、沸水100℃记录传感器读数滑动平均滤波减少随机误差#define FILTER_LEN 5 float temp_history[FILTER_LEN]; uint8_t filter_idx 0; float get_filtered_temp(void) { float sum 0; temp_history[filter_idx] DS18B20_ReadTemp(); filter_idx (filter_idx 1) % FILTER_LEN; for(int i0; iFILTER_LEN; i) { sum temp_history[i]; } return sum / FILTER_LEN; }4. 用户界面实现4.1 OLED显示驱动我们使用SSD1306驱动的OLED屏通过I2C接口通信。首先移植OLED驱动库在CubeMX中启用I2C1速度设为400kHz添加SSD1306驱动文件到项目实现基础显示函数// OLED初始化 void OLED_Init(void) { OLED_WR_Byte(0xAE, OLED_CMD); // 关闭显示 OLED_WR_Byte(0xD5, OLED_CMD); // 设置时钟分频 OLED_WR_Byte(0x80, OLED_CMD); // ... 其他初始化命令 OLED_WR_Byte(0xAF, OLED_CMD); // 开启显示 } // 显示温度界面 void show_temp_screen(float temp) { OLED_Clear(); OLED_ShowString(0, 0, Temp Monitor, 16); OLED_ShowString(0, 2, Current:, 16); OLED_ShowNum(72, 2, (int)temp, 3, 16); OLED_ShowString(108, 2, C, 16); OLED_ShowString(0, 4, Set Range:, 16); OLED_ShowNum(72, 4, temp_low, 2, 16); OLED_ShowString(96, 4, -, 16); OLED_ShowNum(108, 4, temp_high, 2, 16); }4.2 报警功能实现温度报警功能通过LED和蜂鸣器可选实现void check_temp_alarm(float temp) { static uint8_t alarm_state 0; if(temp temp_high) { HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_SET); alarm_state 1; } else if(temp temp_low) { HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_SET); alarm_state 1; } else if(alarm_state) { HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_RESET); alarm_state 0; } }5. 系统整合与优化5.1 主程序逻辑设计系统采用状态机架构确保各功能模块协调工作typedef enum { STATE_NORMAL, STATE_SET_LOW, STATE_SET_HIGH } SystemState; void main(void) { SystemState state STATE_NORMAL; float current_temp; HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_I2C1_Init(); OLED_Init(); DS18B20_Init(); while(1) { current_temp get_filtered_temp(); switch(state) { case STATE_NORMAL: show_temp_screen(current_temp); check_temp_alarm(current_temp); break; case STATE_SET_LOW: // 温区设置逻辑 break; case STATE_SET_HIGH: // 温区设置逻辑 break; } HAL_Delay(1000); } }5.2 功耗优化技巧对于电池供电的应用可采取以下措施降低功耗传感器间歇工作每10秒唤醒一次DS18B20OLED局部刷新只更新变化的部分区域低功耗模式在空闲时进入STOP模式void enter_low_power_mode(void) { HAL_SuspendTick(); HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); SystemClock_Config(); // 唤醒后重新配置时钟 HAL_ResumeTick(); }6. 进阶功能扩展完成基础功能后可以考虑添加以下增强特性历史数据记录利用STM32内部Flash储温度日志蓝牙传输通过HC-05模块将数据发送到手机多传感器网络并联多个DS18B20实现区域监测Web界面通过ESP8266实现远程监控// 多传感器读取示例 void read_multiple_sensors(void) { DS18B20_Reset(); DS18B20_WriteByte(0x55); // 匹配ROM命令 DS18B20_WriteROM(rom_code); // 发送特定传感器ROM码 DS18B20_WriteByte(0x44); // 启动转换 }在实际项目中我发现DS18B20的防水型号特别适合户外应用但要注意导线接头处的密封处理。对于需要快速响应的场景可以将采样间隔缩短到500ms同时适当减少滤波窗口大小。