尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

基于STM32F103C8T6与DS18B20的温度测量系统

基于STM32F103C8T6与DS18B20的温度测量系统
📅 发布时间:2026/6/19 14:49:30

基于STM32F103C8T6(Blue Pill开发板)和DS18B20温度传感器的温度测量系统实现

系统概述

这个系统使用STM32F103C8T6单片机读取DS18B20数字温度传感器的数据,并通过串口将温度值发送到电脑或其他设备显示。DS18B20是一款常用的数字温度传感器,具有单总线接口、高精度(±0.5°C)和可编程分辨率等特点。

硬件设计

所需组件

  1. STM32F103C8T6开发板(Blue Pill)
  2. DS18B20温度传感器
  3. 4.7kΩ上拉电阻
  4. 面包板和连接线

电路连接

STM32F103C8T6 DS18B20
3.3V VDD
GND GND
PA0 (或其他GPIO) DQ

在DQ线和3.3V之间连接一个4.7kΩ的上拉电阻。

软件实现

1. 单总线协议实现

首先,我们需要实现DS18B20的单总线通信协议。创建一个ds18b20.h头文件:

#ifndef DS18B20_H
#define DS18B20_H#include "stm32f1xx_hal.h"// 定义DS18B20引脚
#define DS18B20_PORT GPIOA
#define DS18B20_PIN GPIO_PIN_0// 函数声明
void DS18B20_Init(void);
void DS18B20_StartConversion(void);
float DS18B20_ReadTemperature(void);
uint8_t DS18B20_ReadByte(void);
void DS18B20_WriteByte(uint8_t data);
void DS18B20_SetResolution(uint8_t resolution);#endif

创建ds18b20.c源文件实现单总线协议:

#include "ds18b20.h"
#include "main.h"// 微秒级延迟函数
static void Delay_us(uint32_t us) {us *= (SystemCoreClock / 1000000) / 5;while (us--) {__NOP();}
}// 初始化DS18B20
void DS18B20_Init(void) {GPIO_InitTypeDef GPIO_InitStruct = {0};// 使能GPIOA时钟__HAL_RCC_GPIOA_CLK_ENABLE();// 配置GPIO引脚GPIO_InitStruct.Pin = DS18B20_PIN;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; // 开漏输出GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(DS18B20_PORT, &GPIO_InitStruct);// 设置高电平HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_SET);
}// 发送复位脉冲并检测存在脉冲
uint8_t DS18B20_Reset(void) {uint8_t presence = 0;// 拉低总线480usHAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_RESET);Delay_us(480);// 释放总线HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_SET);Delay_us(70);// 检测存在脉冲if (!HAL_GPIO_ReadPin(DS18B20_PORT, DS18B20_PIN)) {presence = 1; // 设备存在}Delay_us(410);return presence;
}// 从DS18B20读取一个字节
uint8_t DS18B20_ReadByte(void) {uint8_t value = 0;for (uint8_t i = 0; i < 8; i++) {// 拉低总线1usHAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_RESET);Delay_us(1);// 释放总线HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_SET);Delay_us(10);// 读取位if (HAL_GPIO_ReadPin(DS18B20_PORT, DS18B20_PIN)) {value |= (1 << i);}Delay_us(50);}return value;
}// 向DS18B20写入一个字节
void DS18B20_WriteByte(uint8_t data) {for (uint8_t i = 0; i < 8; i++) {// 拉低总线HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_RESET);Delay_us(1);// 如果当前位是1,则释放总线;如果是0,保持低电平if (data & (1 << i)) {HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_SET);}Delay_us(60);// 释放总线HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_SET);Delay_us(1);}
}// 开始温度转换
void DS18B20_StartConversion(void) {DS18B20_Reset();DS18B20_WriteByte(0xCC); // 跳过ROM命令DS18B20_WriteByte(0x44); // 开始转换命令
}// 读取温度值
float DS18B20_ReadTemperature(void) {uint8_t temp_lsb, temp_msb;int16_t temp_raw;float temperature;DS18B20_Reset();DS18B20_WriteByte(0xCC); // 跳过ROM命令DS18B20_WriteByte(0xBE); // 读取暂存器命令// 读取温度值(前两个字节)temp_lsb = DS18B20_ReadByte();temp_msb = DS18B20_ReadByte();// 组合温度值temp_raw = (temp_msb << 8) | temp_lsb;// 转换为实际温度值temperature = temp_raw * 0.0625;return temperature;
}// 设置分辨率
void DS18B20_SetResolution(uint8_t resolution) {uint8_t config;DS18B20_Reset();DS18B20_WriteByte(0xCC); // 跳过ROM命令DS18B20_WriteByte(0x4E); // 写暂存器命令// 写TH和TL寄存器(这里设置为0)DS18B20_WriteByte(0x00);DS18B20_WriteByte(0x00);// 写配置寄存器switch (resolution) {case 9:config = 0x1F;break;case 10:config = 0x3F;break;case 11:config = 0x5F;break;case 12:default:config = 0x7F;break;}DS18B20_WriteByte(config);// 保存配置DS18B20_Reset();DS18B20_WriteByte(0xCC); // 跳过ROM命令DS18B20_WriteByte(0x48); // 复制暂存器命令Delay_us(100);
}

2. 主程序实现

创建main.c文件:

#include "stm32f1xx_hal.h"
#include "ds18b20.h"
#include <stdio.h>// 串口句柄
UART_HandleTypeDef huart1;// 函数声明
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
void Error_Handler(void);int main(void) {float temperature;char msg[50];// HAL库初始化HAL_Init();// 系统时钟配置SystemClock_Config();// 外设初始化MX_GPIO_Init();MX_USART1_UART_Init();// DS18B20初始化DS18B20_Init();// 设置DS18B20分辨率为12位DS18B20_SetResolution(12);// 发送欢迎消息const char *welcome_msg = "DS18B20 Temperature Monitoring System\r\n";HAL_UART_Transmit(&huart1, (uint8_t*)welcome_msg, strlen(welcome_msg), HAL_MAX_DELAY);while (1) {// 启动温度转换DS18B20_StartConversion();// 等待转换完成(最大750ms for 12-bit resolution)HAL_Delay(750);// 读取温度值temperature = DS18B20_ReadTemperature();// 格式化温度字符串sprintf(msg, "Temperature: %.2f C\r\n", temperature);// 通过串口发送温度值HAL_UART_Transmit(&huart1, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);// 等待1秒HAL_Delay(1000);}
}// 系统时钟配置
void SystemClock_Config(void) {RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};// 配置HSE振荡器RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;HAL_RCC_OscConfig(&RCC_OscInitStruct);// 配置系统时钟RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
}// USART1初始化
static void MX_USART1_UART_Init(void) {huart1.Instance = USART1;huart1.Init.BaudRate = 115200;huart1.Init.WordLength = UART_WORDLENGTH_8B;huart1.Init.StopBits = UART_STOPBITS_1;huart1.Init.Parity = UART_PARITY_NONE;huart1.Init.Mode = UART_MODE_TX_RX;huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;huart1.Init.OverSampling = UART_OVERSAMPLING_16;HAL_UART_Init(&huart1);
}// GPIO初始化
static void MX_GPIO_Init(void) {// 无需额外GPIO初始化,DS18B20的初始化在DS18B20_Init()中完成
}// 错误处理函数
void Error_Handler(void) {while (1) {// 错误处理代码}
}// 重写fputc函数,支持printf
int fputc(int ch, FILE *f) {HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, HAL_MAX_DELAY);return ch;
}

3. 添加必要的支持文件

创建stm32f1xx_it.c文件处理中断:

#include "stm32f1xx_it.h"void NMI_Handler(void) {
}void HardFault_Handler(void) {while (1) {}
}void SVC_Handler(void) {
}void PendSV_Handler(void) {
}void SysTick_Handler(void) {HAL_IncTick();
}

参考代码 基于STM32F103C8T6单片机与DS18B20温度传感器的温度测量 www.youwenfan.com/contentcnh/56802.html

使用

  1. 按照电路连接图连接STM32F103C8T6和DS18B20
  2. 使用STM32CubeIDE或Keil MDK创建新项目
  3. 将上述代码添加到项目中
  4. 配置项目设置,确保正确选择STM32F103C8T6芯片
  5. 编译并下载程序到开发板
  6. 使用串口调试工具(如Putty、Tera Term等)连接开发板的串口(波特率115200)
  7. 观察温度数据输出

扩展

  1. 多传感器支持:DS18B20支持单总线上连接多个传感器,可以通过读取每个传感器的唯一ROM地址来实现多传感器测量。

  2. 温度报警:可以设置温度上下限,当温度超出范围时触发报警。

  3. LCD显示:添加LCD显示屏,直接显示温度值,而不需要通过串口。

  4. 数据记录:添加SD卡模块,将温度数据记录到文件中。

  5. 无线传输:添加Wi-Fi或蓝牙模块,实现无线温度监控。

相关新闻

  • Oxygen Forensic Detective 18.0 发布,新增功能简介
  • Windows如何美化cmd窗口
  • MX Round 7 解题报告

最新新闻

  • 如何轻松下载Sketchfab模型:零基础用户的完整免费方案
  • 标准化原厂修护|2026年6月万国官方售后门店详细地址,官方咨询电话随时对接 - 速递信息
  • 真实资质实地核验|2026 年 6 月万国全国官方维修中心线下调研实录,60 余家品牌合规门店全新走访数据汇总 - 万国中国服务中心
  • 2026年6月最新卡地亚中国官方售后网点电话地址及客户服务中心 - 卡地亚服务中心
  • 大模型竞赛实战路线:从3090显存限制到Kaggle提交的硬核路径
  • TMS320F28335与XDS100V3使用问题记录

日新闻

  • 信任的进化:技术实现详解——如何用JavaScript构建博弈论模拟器
  • Terrakube自定义工作流:如何集成OPA、Infracost等工具扩展IaC能力
  • grunt-concurrent快速入门:5分钟学会并行运行Grunt任务

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号