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摄氏度,测量精度非常可观。

 六、特别说明

  • 同学们在操作的过程中遇到的问题可在评论区留言,我看到后会第一时间回复。
  • 想看其他传感器的教程也可在评论区留言,我会按照大家的需求来修改教程内容。
  • 若您觉得本教程对您有所帮助,请点赞、收藏,这是我持续更新的最大动力,感谢您!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/442892.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【vue2.7.16系列】手把手教你搭建后台系统__配置路由(3)

新建页面 我们把 components 改名为 views&#xff0c;并在 views 目录下添加三个页面&#xff0c;Login.vue&#xff0c;Home.vue&#xff0c;404.vue。 三个页面内容简单相似&#xff0c;只有简单的页面标识&#xff0c;如首页页面是 “Home Page”。 Home.vue&#xff0c;…

NVLink 和 NVLink Switch

高速、多 GPU 通信的基础模组,助力将大型数据集更快地输入模型并在 GPU 之间快速交换数据。 文章目录 前言一、简介二、NVLink 性能三、NVLink Switch1. 通过 NVLink 通信提高 GPU 吞吐量2. NVIDIA NVLink 交换机四、NVLink Switch规格1. 通过完全连接实现非凡性能2. 功能强大…

【C++】:bind绑定器和function函数对象机制

欢迎来到 破晓的历程的 博客 ⛺️不负时光&#xff0c;不负己✈️ 文章目录 引言function函数对象function引入细讲function体验function在工程实践中的优势 模拟实现function函数对象机制bind绑定器基本语法示例1. 绑定普通函数2. 使用占位符3. 绑定成员函数4. 绑定 lambda 表…

【汇编语言】寄存器(CPU工作原理)(六)—— 修改CS,IP的指令以及代码段

文章目录 前言1. 修改CS、IP的指令2. 问题分析:CPU运行的流程3. 代码段小结结语 前言 &#x1f4cc; 汇编语言是很多相关课程&#xff08;如数据结构、操作系统、微机原理&#xff09;的重要基础。但仅仅从课程的角度出发就太片面了&#xff0c;其实学习汇编语言可以深入理解计…

基于SpringBoot在线拍卖系统【附源码】

基于SpringBoot在线拍卖系统 效果如下&#xff1a; 网站首页界面 用户登录界面 竞拍商品界面 管理员登录界面 管理员功能界图 竞拍商品界面 系统界面 订单界面 研究背景 随着社会的发展&#xff0c;信息化时代带来了各行各业的变革。电子商务已成为人们日常生活不可或缺的一…

【重学 MySQL】四十四、相关子查询

【重学 MySQL】四十四、相关子查询 相关子查询执行流程示例使用相关子查询进行过滤使用相关子查询进行存在性检查使用相关子查询进行计算 在 select&#xff0c;from&#xff0c;where&#xff0c;having&#xff0c;order by 中使用相关子查询举例SELECT 子句中使用相关子查询…

刷题 -哈希

面试面试经典 150 题 - 哈希 383. 赎金信 - 一个哈希表搞定 class Solution { public:bool canConstruct(string ransomNote, string magazine) {int hash[26] {0};for (auto& ch : magazine) {hash[ch - a];}for (auto& ch : ransomNote) {if (--hash[ch - a] < …

Linux的六个入侵检查思路及预防

背景 入侵检查是保障计算机安全运行的重要手段之一&#xff0c; 通过操作系统的静态配置分析、日志分析、异常行为分析以及文件完整性等方式来做检查&#xff0c;来判断我们的操作系统是否有受到入侵。今天阿祥就介绍十个简单的入侵检查思路及应对措施&#xff0c;希望对大家有…

原生USDC正式上线Sui

今天&#xff0c;标志着Sui生态的一个重要里程碑 — — 原生USDC现已正式在Sui主网上线。作为最广泛使用的稳定币之一&#xff0c;USDC为日益增长的Sui生态带来了稳定的价值传输和流动性。 随着Sui DeFi锁仓量&#xff08;TVL&#xff09;突破10亿美元&#xff0c;网络上需要更…

Linux同时安装多个JDK

Linux同时安装多个JDK 一、JDK1.1、JDK的下载1.2、解压并放置目录 二、通过alias切换版本2.1、修改profile文件2.2、使用和验证 三、使用update-alternatives工具3.1、修改profile文件3.2、指定JDK版本3.3、使用和验证 四、总结 一、JDK 1.1、JDK的下载 JDK官网下载&#xff…

无人机之飞行算法篇

无人机的飞行算法是一个复杂而精细的系统&#xff0c;它涵盖了多个关键技术和算法&#xff0c;以确保无人机能够稳定、准确地执行飞行任务。 一、位置估计 无人机在空中飞行过程中需要实时获取其位置信息&#xff0c;以便进行路径规划和控制。这通常通过以下传感器实现&#…

Rust编程中的循环语句

【图书介绍】《Rust编程与项目实战》-CSDN博客 《Rust编程与项目实战》(朱文伟&#xff0c;李建英)【摘要 书评 试读】- 京东图书 (jd.com) Rust编程与项目实战_夏天又到了的博客-CSDN博客 6.2 for 循 环 迭代次数是确定/固定的循环称为确定循环。for 循环是一个确定循环…

新书速览|你好,C++

《你好&#xff0c;C》 本书内容 《你好&#xff0c;C》主要介绍C开发环境的搭建、基础语法知识、面向对象编程思想以及标准模板库的应用&#xff0c;特别针对初学者在学习C过程中可能遇到的难点提供了解决方案。全书共分13章&#xff0c;以一个工资程序的不断优化和完善为线索…

速度白嫖:Minimax海螺上线图生视频功能

一、什么是Minimax海螺 网址&#xff1a;https://hailuoai.video/ Minimax海螺是一款创新的内容创作工具&#xff0c;专注于将静态图像转化为动态视频。它利用先进的图像处理与生成算法&#xff0c;帮助用户将普通图片迅速转变为引人入胜的短视频&#xff0c;适合社交媒体、…

【HarmonyOS开发笔记 1】 -- 开发环境的搭建

DevEco Studio 的下载与安装 下载 下载路径&#xff1a; https://developer.huawei.com/consumer/cn/download/ 安装 解压后双击 deveco-studio-5.0.3.814.exe 指定安装目录&#xff0c;或者默认&#xff0c;然后下一步 一直“下一步”&#xff0c; 直到最后安装完成 新…

视频消重pr模板|胶片损伤特效视频去重pr模板工程文件

可以用于视频消重效果的pr去重模板&#xff0c;10种胶片损伤特效视频叠加素材pr工程文件。 Premiere Pro模板&#xff0c;可以使用这些效果来增强您的媒体。音乐不包括在内。 下载地址&#xff1a;Pr模板网 下载链接&#xff1a;https://prmuban.com/40591.html

分享我“Excel 表格”关键字的博客笔记(python脚本全程自动)

Python脚本全程自动&#xff0c;全部Python内建工具脚本纯净。 (笔记模板由python脚本于2024年10月05日 19:51:06创建&#xff0c;本篇笔记适合喜欢Excel和Python的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大…

Qt - QMenu

QMenu 1、menu转string输出 //GlobalEnum.h #include <QObject> #include <QMetaEnum> class GlobalEnum : public QObject {Q_OBJECT public:EnumTest();enum Enum_Test{ZhangSan 0,WangWu,};Q_ENUM(Enum_Test) };#define EnumToString(e) \ QMetaEnum::fromTy…

手把手教你如何配置好VS Code的WEB基础开发环境(保姆级)

1. VS Code介绍 微软旗下的多场景开发环境软件&#xff0c;支持JAVA、C、C#、C、WEB、VUE、CSS、HTML、Python等等等 如果你刚刚开始编程或者准备学习WEB&#xff0c;那么我强烈建议你使用这款软件 缺点&#xff1a;&#xff08;针对初学者&#xff09; 需要安装各种各样的插…

数据分析-29-基于pandas的窗口操作和对JSON格式数据的处理

文章目录 1 窗口操作1.1 滑动窗口思想1.2 函数df.rolling2 JSON格式数据2.1 处理简单JSON对象和JSON列表2.1.1 处理简单的JSON结构2.1.2 处理空字段2.1.3 获取部分字段2.2 处理多级json2.2.1 展开所有级别(默认)2.2.2 自定义展开层级2.3 处理嵌套列表JSON3 参考附录1 窗口操作 …