STM32-HAL库 驱动DS18B20温度传感器 -- 2024.10.8
目录
一、教程简介
二、驱动理论讲解
三、CubeMX生成底层代码
四、Keil5编写代码
五、实验结果
一、教程简介
本教程面向初学者,只介绍DS18B20的常用功能,但也能满足大部分的运用需求。跟着本教程操作,可在10分钟内解决DS18b20通信难题。
二、驱动理论讲解
DS18b20支持多传感器共用一个引脚,但本教程只教使用一个温湿度传感器。使用DS18b20可分为下面两个步骤进行
(一)初始化:
1、将引脚初始化为推挽输出、上拉。
2、发送复位脉冲:引脚输出大于480us的低电平复位信号(建议600us),延时600us之后,需将引脚拉高并延时15us。
3、检测存在脉冲:将引脚设置为上拉输入,并检测低电平到来的时间,若超过100us还没检测到低电平,则初始化失败。检测到低电平后开始计算时间,若低超过240us还没检测到高电平,则初始化失败。
(二)获取温度:
1、配置单DS18b20模式:重复初始化操作后发送命令:0xCC
2、发送温度转换命令:发送0x44
3、配置单DS18b20模式:重复初始化操作后发送命令:0xCC
4、发送读取命令:发送0xBE
5、接收两个字节的温度数据
三、CubeMX生成底层代码
1、芯片选择:这里选用STM32F103C8t6
2、配置Debug模式
3、 配置外部高速时钟
4、 配置时钟速率
5、 配置DS18b20引脚
6、配置串口
7、输出工程文件
四、Keil5编写代码
1、ds18b20.c 代码
/* 包含头文件 ----------------------------------------------------------------*/
#include "ds18b20.h"/*** 函数功能: DS18B20 初始化函数* 返 回 值: 1为初始化失败,0为初始化成功*/
uint8_t DS18B20_Init(void)
{DS18B20_Mode_Out_PP(); //推挽输出模式DS18B20_Dout_HIGH(); //输出高电平DS18B20_Rst(); //输出复位脉冲return DS18B20_Presence (); //返回响应情况
}/*** 函数功能: 使DS18B20-DATA引脚变为上拉输入模式*/
static void DS18B20_Mode_IPU(void)
{GPIO_InitTypeDef GPIO_InitStruct;/* 串口外设功能GPIO配置 */GPIO_InitStruct.Pin = DS18b20_Pin;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init(DS18b20_GPIO_Port, &GPIO_InitStruct);}/*** 函数功能: 使DS18B20-DATA引脚变为推挽输出模式*/
static void DS18B20_Mode_Out_PP(void)
{GPIO_InitTypeDef GPIO_InitStruct;/* 串口外设功能GPIO配置 */GPIO_InitStruct.Pin = DS18b20_Pin;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(DS18b20_GPIO_Port, &GPIO_InitStruct);
}/*** 函数功能: 主机给从机发送复位脉冲*/
static void DS18B20_Rst(void)
{DS18B20_Mode_Out_PP(); /* 主机设置为推挽输出 */DS18B20_Dout_LOW(); /* 主机输出低电平 */DS18B20_Delay(750); /* 主机至少产生480us的低电平复位信号 */DS18B20_Dout_HIGH(); /* 主机在产生复位信号后,需将总线拉高 */DS18B20_Delay(15); /* 从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲 */
}/*** 函数功能: 检测从机给主机返回的存在脉冲* 返 回 值: 0:成功,1:失败*/static uint8_t DS18B20_Presence(void)
{uint8_t pulse_time = 0;/* 主机设置为上拉输入 */DS18B20_Mode_IPU();/* 等待存在脉冲的到来,存在脉冲为一个60~240us的低电平信号 * 如果存在脉冲没有来则做超时处理,从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲*/while( DS18B20_Data_IN() && pulse_time<100 ){pulse_time++;DS18B20_Delay(1);} /* 经过100us后,存在脉冲都还没有到来*/if( pulse_time >=100 )return 1;elsepulse_time = 0;/* 存在脉冲到来,且存在的时间不能超过240us */while( !DS18B20_Data_IN() && pulse_time<240 ){pulse_time++;DS18B20_Delay(1);} if( pulse_time >=240 )return 1;elsereturn 0;
}/*** 函数功能: 从DS18B20读取一个bit* 返 回 值: 读取到的数据*/
static uint8_t DS18B20_ReadBit(void)
{uint8_t dat;/* 读0和读1的时间至少要大于60us */ DS18B20_Mode_Out_PP();/* 读时间的起始:必须由主机产生 >1us <15us 的低电平信号 */DS18B20_Dout_LOW();DS18B20_Delay(10);/* 设置成输入,释放总线,由外部上拉电阻将总线拉高 */DS18B20_Mode_IPU();//Delay_us(2);if( DS18B20_Data_IN() == SET )dat = 1;elsedat = 0;/* 这个延时参数请参考时序图 */DS18B20_Delay(45);return dat;
}/*** 函数功能: 从DS18B20读一个字节,低位先行* 返 回 值: 读到的数据*/
static uint8_t DS18B20_ReadByte(void)
{uint8_t i, j, dat = 0; for(i=0; i<8; i++) {j = DS18B20_ReadBit(); dat = (dat) | (j<<i);}return dat;
}/*** 函数功能: 写一个字节到DS18B20,低位先行* 输入参数: dat:待写入数据*/
static void DS18B20_WriteByte(uint8_t dat)
{uint8_t i, testb;DS18B20_Mode_Out_PP();for( i=0; i<8; i++ ){testb = dat&0x01;dat = dat>>1; /* 写0和写1的时间至少要大于60us */if (testb){ DS18B20_Dout_LOW();/* 1us < 这个延时 < 15us */DS18B20_Delay(8);DS18B20_Dout_HIGH();DS18B20_Delay(58);} else{ DS18B20_Dout_LOW();/* 60us < Tx 0 < 120us */DS18B20_Delay(70);DS18B20_Dout_HIGH(); /* 1us < Trec(恢复时间) < 无穷大*/DS18B20_Delay(2);}}
}/*** 函数功能: 跳过匹配 DS18B20 ROM*/
static void DS18B20_SkipRom ( void )
{DS18B20_Rst(); DS18B20_Presence(); DS18B20_WriteByte(0XCC); /* 跳过 ROM */
}/*** 函数功能: 获取 DS18B20 温度值 * 返 回 值: 浮点型温度值*/
float DS18B20_GetTemp_SkipRom ( void )
{uint8_t tpmsb, tplsb;short s_tem;float f_tem;DS18B20_SkipRom ();DS18B20_WriteByte(0X44); /* 开始转换 */DS18B20_SkipRom ();DS18B20_WriteByte(0XBE); /* 读温度值 */tplsb = DS18B20_ReadByte(); tpmsb = DS18B20_ReadByte(); s_tem = tpmsb<<8;s_tem = s_tem | tplsb;if( s_tem < 0 ) /* 负温度 */f_tem = (~s_tem+1) * 0.0625; elsef_tem = s_tem * 0.0625;return f_tem;
}/*** 微妙延时函数* 全系列通用,只需要将宏定义CPU_FREQUENCY_MHZ根据时钟主频修改即可。* 系统滴答定时器是HAL库初始化的,且必须有HAL库初始化。*/
#define CPU_FREQUENCY_MHZ (int)(HAL_RCC_GetHCLKFreq()/1000000) // 自动获取STM32时钟主频
void DS18B20_Delay(__IO uint32_t delay)
{int last, curr, val;int temp;while (delay != 0){temp = delay > 900 ? 900 : delay;last = SysTick->VAL;curr = last - CPU_FREQUENCY_MHZ * temp;if (curr >= 0){do{val = SysTick->VAL;}while ((val < last) && (val >= curr));}else{curr += CPU_FREQUENCY_MHZ * 1000;do{val = SysTick->VAL;}while ((val <= last) || (val > curr));}delay -= temp;}
}
2、ds18b20.h 代码
#ifndef __DS18B20_H
#define __DS18B20_H/* 包含头文件 ----------------------------------------------------------------*/
#include "main.h"/* 引脚操作函数宏定义 --------------------------------------------------------*/
#define DS18B20_Dout_LOW() HAL_GPIO_WritePin(DS18b20_GPIO_Port,DS18b20_Pin,GPIO_PIN_RESET)
#define DS18B20_Dout_HIGH() HAL_GPIO_WritePin(DS18b20_GPIO_Port,DS18b20_Pin,GPIO_PIN_SET)
#define DS18B20_Data_IN() HAL_GPIO_ReadPin(DS18b20_GPIO_Port,DS18b20_Pin)/* 函数声明 ------------------------------------------------------------------*/
void DS18B20_Rst(void);
void DS18B20_SkipRom(void);
void DS18B20_Mode_IPU(void);
void DS18B20_Mode_Out_PP(void);
void DS18B20_WriteByte(uint8_t dat);
void DS18B20_Delay(__IO uint32_t delay);
float DS18B20_GetTemp_SkipRom(void);
uint8_t DS18B20_Init(void);
uint8_t DS18B20_ReadBit(void);
uint8_t DS18B20_Presence(void);
uint8_t DS18B20_ReadByte(void);#endif
3、main.c 参考调用代码
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usart.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "ds18b20.h"
#include "stdio.h"
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
char Tx_Buf[30] = {0};
float Temp = 0;
/* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//* USER CODE END 0 *//*** @brief The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */while(DS18B20_Init()){HAL_UART_Transmit(&huart1,(uint8_t*)"DS18b20初始化失败\r\n",19,100);HAL_Delay(1000);}HAL_UART_Transmit(&huart1,(uint8_t*)"DS18b20初始化成功\r\n",19,100);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){Temp = DS18B20_GetTemp_SkipRom();sprintf(Tx_Buf,"温度:%0.3f \r\n",Temp);HAL_UART_Transmit(&huart1,(uint8_t*)Tx_Buf,15,100);HAL_Delay(1000);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}
五、实验结果
通过本驱动使用DS18b20测量出来的环境温度,与米家温湿度计测量的结果仅仅相差0.012摄氏度,测量精度非常可观。
六、特别说明
- 同学们在操作的过程中遇到的问题可在评论区留言,我看到后会第一时间回复。
- 想看其他传感器的教程也可在评论区留言,我会按照大家的需求来修改教程内容。
- 若您觉得本教程对您有所帮助,请点赞、收藏,这是我持续更新的最大动力,感谢您!
相关文章:

STM32-HAL库 驱动DS18B20温度传感器 -- 2024.10.8
目录 一、教程简介 二、驱动理论讲解 三、CubeMX生成底层代码 四、Keil5编写代码 五、实验结果 一、教程简介 本教程面向初学者,只介绍DS18B20的常用功能,但也能满足大部分的运用需求。跟着本教程操作,可在10分钟内解决DS18b20通信难题。…...
HTML 符号
HTML 符号 HTML(超文本标记语言)是一种用于创建网页的标准标记语言。它使用一系列的标签来描述网页的结构和内容。HTML 符号,通常指的是 HTML 标签,是构成 HTML 文档的基础。本文将详细介绍 HTML 符号的概念、种类、用途以及如何在网页设计中正确使用它们。 HTML 符号的概…...
编译后的MySQL安装
MySQL安装 1.下载网址2.下载方式3.配置配置环境变量修改配置文件初始化安装服务启动服务测试修改 Mysql 默认密码 1.下载网址 https://dev.mysql.com/downloads/mysql/2.下载方式 选择对应版本下载 mysql-xxx-winx64.zip,该压缩包为编译后文件,并非源码…...

Ubuntu安装Apache教程
系统版本:Ubuntu版本 23.04 Ubuntu是一款功能强大且用户友好的操作系统,而Apache是一款广泛使用的Web服务器软件。在Ubuntu上安装Apache可以帮助用户搭建自己的网站或者进行Web开发。为大家介绍如何在Ubuntu上安装Apache,并提供详细的教程和操…...

Nginx跳转模块之location与rewrite
目录 一、location模块与rewrite模块区别 二、location模块的基本介绍 1. location模块是什么? 2. 三种匹配类别 3. 常用的匹配规则 4. 匹配优先级 三、location模块使用实例 1.精准匹配优先级小于一般匹配的特殊情况 2 .解决方法 3. 实际网站使用中的三个匹配…...
oracle col命令
oracle col命令可以对列进行进行格式化,格式:col 列名 for(mat) 格式 例如: col owner for a100 设置owner列格式 col 列名:显示当前列的格式 SQL> col owner COLUMN owner ON FORMAT a100 SQL> clear column:清除所有列的格式 SQL> col o…...

ESP32接入扣子(Coze) API使用自定义智能体
使用ESP32接入Coze API实现聊天机器人的教程 本示例将使用ESP32开发板通过WiFi接入 Coze API,实现一个简单的聊天机器人功能。用户可以通过串口向机器人输入问题,ESP32将通过Coze API与智能体进行通信,并返回对应的回复。本文将详细介绍了如…...

【JVM】如何判断对象是否可以被回收
引用计数法: 在对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加一;当引用失效时,计数器值就减一;任何时刻计数器为零的对象就是不可能再被使用的。 优点:实现简单,判…...
CloseableHttpResponse 类(代表一个可关闭的 HTTP 响应)
CloseableHttpResponse 类是 Apache HttpClient 库中的一个类,代表一个可关闭的 HTTP 响应。当你使用 HttpClient 发送请求时,你会得到一个 CloseableHttpResponse 实例,它包含了服务器的响应数据和状态。处理完响应后,你应该关闭…...
C语言编程规范及命名规则
C语言编程规范及命名规则 编码规范总原则:清晰、简洁、一致头文件函数标识符命名与定义变量宏、常量表达式注释排版与格式代码编辑编译其他设置 命名规则类型命名: 其他编译器配色 参考 编码规范 总原则:清晰、简洁、一致 清晰第一 清晰性是…...

Pika 1.5 - Pika Labs最新推出的AI视频生成工具
Pika 1.5是由Pika Labs最新推出的AI视频生成工具。通过简单易用的界面和强大的”Pikaffects”特效库,用户能通过上传图片或输入文本,快速生成具有专业质感和创意效果的视频内容。新版本强调低门槛创作,让普通用户能轻松制作出有趣、抽象、易于…...

Elon Musk 正式揭晓了特斯拉的Robotaxi和Robovan,这两款自动驾驶新车型成为发布会上的焦点
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
博客摘录「 springboot+netty+mqtt服务端实现」2024年10月11日
try {MqttPublishMessage mqttPublishMessage (MqttPublishMessage) mqttMessage;ByteBuf byteBuf mqttPublishMessage.payload();byteBuf.retainedDuplicate();ctx.writeAndFlush(mqttPublishMessage);} catch (Exception e) {e.printStackTrace();throw e;}...
Docker小白入门笔记
Docker 命令笔记 Docker Desktop 1.构建镜像 无缓存构建: docker build --no-cache -t image_name .普通构建: docker build -t image_name . 2.运行容器 docker run -d --name docker_name -p 9000:9000 --env-file "path\.env" image_name参数说明:…...

Unity 如何在 iOS 新增键盘 KeyCode 响应事件
1.定位到文件UnityViewKeyboard.mm同如下路径: 2.打开该Objective-C脚本进行编辑,找到关键函数: createKeyboard: - (void)createKeyboard {// only English keyboard layout is supportedNSString* baseLayout "1234567890-qwertyuiop[]asdfghjkl;\\zxcvbnm,./!#$%^&am…...

pytorh学习笔记——波士顿房价预测
机器学习的“hello world”:波士顿房价预测 波士顿房价预测的背景不用提了,简单了解一下数据集的结构。 波士顿房价的数据集,共有506组数据,每组数据共14项,前13项是影响房价的各种因素,比如&…...

让AI像人一样思考和使用工具,reAct机制详解
reAct机制详解 reAct是什么reAct的关键要素reAct的思维过程reAct的代码实现查看效果引入依赖,定义模型定义相关工具集合工具创建代理启动测试完整代码 思考 reAct是什么 reAct的核心思想是将**推理(Reasoning)和行动(Acting&…...

Linux系列-常见的指令(二)
🌈个人主页: 羽晨同学 💫个人格言:“成为自己未来的主人~” mv 剪切文件,目录 重命名 比如说,我们在最开始创建一个新的文件hello.txt 然后我们将这个文件改一个名字,改成world.txt 所以,…...

Leecode刷题之路第17天之电话号码的字母组合
题目出处 17-电话号码的字母组合-题目出处 题目描述 个人解法 思路: todo 代码示例:(Java) todo复杂度分析 todo 官方解法 17-电话号码的字母组合-官方解法 方法1:回溯 思路: 代码示例:&a…...

2023牛客暑期多校训练营3(题解)
今天下午也是小小的做了一下,OI,也是感觉手感火热啊,之前无意间看到的那个哥德巴赫定理今天就用到了,我以为根本用不到的,当时也只是感兴趣看了一眼,还是比较激动啊 话不多说,直接开始看题 Wo…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...

基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...

visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...

Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...