基于HAL库stm32f1的DS18B20温度传感器

2023-11-02

由于做比赛,所以写了温度传感器,记录一下

一.介绍

DS18B20是常用的数字温度传感器,其输出的是数字信号,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。 [1] DS18B20数字温度传感器接线方便,封装成后可应用于多种场合,如管道式,螺纹式,磁铁吸附式,不锈钢封装式,型号多种多样,有LTM8877,LTM8874等等。

主要根据应用场合的不同而改变其外观。封装后的DS18B20可用于电缆沟测温,高炉水循环测温,锅炉测温,机房测温,农业大棚测温,洁净室测温,弹药库测温等各种非极限温度场合。耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温和控制领域。
来源(百度百科)。

初步了解后,有需要的同学可以看一下这篇文章去了解它的原理来自一位很优秀的博主Z小旋

二.cubemx配置以及代码部分

由于DS8B20只有三个引脚,VCC,GND,剩下的引脚接单片机的GPIO口就行,配置为输出上拉模式。


/**
  ******************************************************************************
  * @file            bsp_ds18b20.c
  * @author		
  * @date			
  * @version         v1.0
  * @note            DHT11 driver
  ******************************************************************************
  */
 
#include "ds18b20.h"


void Delay_us(uint32_t time)
{    
   uint8_t i=0;  
   while(time--)
   {
      i=10;  //自己定义
      while(i--) ;    
   }
}


/**
  * @brief DS18B20 输出模式
  */
static void DS18B20_Mode_OUT_PP(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	GPIO_InitStruct.Pin = BSP_DS18B20_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
	
	HAL_GPIO_Init(BSP_DS18B20_PORT, &GPIO_InitStruct);
}
 
/**
  * @brief DS18B20 输入模式
  */
static void DS18B20_Mode_IN_NP(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	GPIO_InitStruct.Pin = BSP_DS18B20_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
 
	HAL_GPIO_Init(BSP_DS18B20_PORT, &GPIO_InitStruct);
}
 
/**
  * @brief 主机给从机发送复位脉冲
  */
static void DS18B20_Reset(void)
{
	DS18B20_Mode_OUT_PP();		// 主机输出
	
	DS18B20_OUT_0;						// 主机至少产生 480us 的低电平复位信号 
	Delay_us(750);
	
	DS18B20_OUT_1;						// 主机在产生复位信号后,需将总线拉高 
	
	// 从机接收到主机的复位信号后,会在 15 ~ 60 us 后给主机发一个存在脉冲
	Delay_us(15);					
}
 
/**
  * @brief  检测从机给主机返回的存在脉冲
  * @return 0:成功		1:失败
	*/
static uint8_t DS18B20_Presence(void)
{
	uint8_t pulse_time = 0;
	
	DS18B20_Mode_IN_NP();				// 主机设为输入 
	
	// 等待存在脉冲的到来,存在脉冲为一个 60 ~ 240 us 的低电平信号 
	// 如果存在脉冲没有来则做超时处理,从机接收到主机的复位信号后,会在 15 ~ 60 us 后给主机发一个存在脉冲
 
	while (DS18B20_IN && (pulse_time < 100))		// 等待低电平响应脉冲
	{
		pulse_time++;
		Delay_us(1);
	}	
	// 经过 100 us 后,存在脉冲都还没有到来
	if (pulse_time >= 100)
	{
		return 1;
	}
	else
	{
		pulse_time = 0;		
	}
		
	// 响应脉冲(低电平)到来,且存在的时间不能超过 240 us 
	while(!(DS18B20_IN) && pulse_time < 240)
	{
		pulse_time++;
		Delay_us(1);
	}	
	if(pulse_time >= 240)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}
 
 /**
   * @brief  DS18B20 初始化函数
   * @reurn  0:成功		1:失败
   */
uint8_t DS18B20_Init(void)
{
	DS18B20_Mode_OUT_PP();
	DS18B20_OUT_1;
	
	DS18B20_Reset();
	return DS18B20_Presence();
}
 
/**
  * @brief 从DS18B20读取一个bit
  */
static uint8_t DS18B20_ReadBit(void)
{
	uint8_t dat;
	
	DS18B20_Mode_OUT_PP();	// 读 0 和读 1 的时间至少要大于 60 us 
	
	DS18B20_OUT_0;					// 读时间的起始:必须由主机产生 > 1us < 15us 的低电平信号 
	
	// 这个时间非常重要,设置为 < 15,需要多次尝试;如果设置不合理,数据会直接出错
	// 参数建议设为 10 11 12,具体值要根据延时函数的执行效率测试
	Delay_us(10);		
	
	DS18B20_Mode_IN_NP();		// 设置成输入,释放总线,由外部上拉电阻将总线拉高 
	
	if (DS18B20_IN == 1)
	{
		dat = 1;
	}
	else
	{
		dat = 0;
	}
		
	Delay_us(45);				// 这个延时参数参考时序图 
	
	return dat;
}
 
/**
  * @brief 从 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;
}
 
/**
  * @brief 写一个字节到 DS18B20,低位先行
  */
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)			// 当前位写 1
		{			
			DS18B20_OUT_0;
			
			Delay_us(5);		// 拉低发送写时段信号
			
			DS18B20_OUT_1;			// 读取电平时间保持高电平
			Delay_us(65);		
		}		
		else						// 当前位写 0			
		{			
			DS18B20_OUT_0;			// 拉低发送写时段信号
			Delay_us(70);		// 读取电平时间保持低电平
			
			DS18B20_OUT_1;				
			Delay_us(2);		// 恢复时间
		}
	}
}
 
/**
  * @brief  跳过匹配 DS18B20 ROM
  */
static void DS18B20_SkipRom(void)
{
	DS18B20_Reset();	   
	
	DS18B20_Presence();	 
	
	DS18B20_WriteByte(0XCC);		/* 跳过 ROM */
}
 
/**
  * @brief  执行匹配 DS18B20 ROM
  */
static void DS18B20_MatchRom(void)
{
	DS18B20_Reset();	   
	
	DS18B20_Presence();	 
	
	DS18B20_WriteByte(0X55);		/* 匹配 ROM */
}
 
/**
	* 存储的温度是16 位的带符号扩展的二进制补码形式
	* 当工作在12位分辨率时,其中5个符号位,7个整数位,4个小数位
	*
	*         |---------整数----------|-----小数 分辨率 1/(2^4)=0.0625----|
	* 低字节  | 2^3 | 2^2 | 2^1 | 2^0 | 2^(-1) | 2^(-2) | 2^(-3) | 2^(-4) |
	*
	*
	*         |-----符号位:0->正  1->负-------|-----------整数-----------|
	* 高字节  |  s  |  s  |  s  |  s  |    s   |   2^6  |   2^5  |   2^4  |
	*
	* 
	* 温度 = 符号位 + 整数 + 小数*0.0625
	*/
 
/**
  * @brief  在跳过匹配 ROM 情况下获取 DS18B20 温度值 
  * @param  无
  * @retval 温度值
  */
float DS18B20_GetTemp_SkipRom(void)
{
	uint8_t tpmsb, tplsb;
	int16_t 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.0625f;	
	}
	else
	{
		f_tem = s_tem * 0.0625f;
	}
		
	return f_tem; 	
}
 
/**
  * @brief  在匹配 ROM 情况下获取 DS18B20 温度值 
  * @param  ds18b20_id:用于存放 DS18B20 序列号的数组的首地址
  */

void DS18B20_ReadId(uint8_t *ds18b20_id)
{
	uint8_t uc;
	
	DS18B20_WriteByte(0x33);       //读取序列号
	
	for (uc = 0; uc < 8; uc++)
	{
		ds18b20_id[uc] = DS18B20_ReadByte();
	}
}
 
/**
  * @brief  在匹配 ROM 情况下获取 DS18B20 温度值 
  * @param  ds18b20_id:存放 DS18B20 序列号的数组的首地址
  * @retval 温度值
  */
float DS18B20_GetTemp_MatchRom(uint8_t * ds18b20_id)
{
	uint8_t tpmsb, tplsb, i;
	int16_t s_tem;
	float f_tem;
	
	DS18B20_MatchRom();            	/* 匹配ROM */
	
  for(i = 0;i < 8; i++)
	{
		DS18B20_WriteByte(ds18b20_id[i]);
	}
		
	DS18B20_WriteByte(0X44);				/* 开始转换 */
 
	DS18B20_MatchRom();            	/* 匹配ROM */
	
	for(i = 0; i < 8; i++)
	{
		DS18B20_WriteByte(ds18b20_id[i]);	
	}
		
	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.0625f;	
	}
	else
	{
		f_tem = s_tem * 0.0625f;
	}
		
	return f_tem; 		
}


#ifndef __DS18B20_H_
#define __DS18B20_H_

#include "stm32f1xx.h"
#include "core_cm3.h"
#include "stm32f1xx_hal.h"
#include "main.h"
#include "gpio.h"
#include "stm32f1xx_hal_gpio.h"
//#include "stdint.h"


#define BSP_DS18B20_PORT             BSP_DS18B20_GPIO_Port
#define BSP_DS18B20_PIN              BSP_DS18B20_Pin
 
#define DS18B20_OUT_1                HAL_GPIO_WritePin(BSP_DS18B20_PORT, BSP_DS18B20_PIN, GPIO_PIN_SET)
#define DS18B20_OUT_0                HAL_GPIO_WritePin(BSP_DS18B20_PORT, BSP_DS18B20_PIN, GPIO_PIN_RESET)
 
#define DS18B20_IN			             HAL_GPIO_ReadPin(BSP_DS18B20_PORT, BSP_DS18B20_PIN)
 
uint8_t DS18B20_Init(void);
void DS18B20_ReadId(uint8_t *ds18b20_id);
float DS18B20_GetTemp_SkipRom(void);
float DS18B20_GetTemp_MatchRom(uint8_t * ds18b20_id);
void Delay_us(uint32_t time);

#endif

在while1中,
在这里插入图片描述
这样调用,也可以用串口打印,看数据会更直观
在这里插入图片描述

这就是结果啦
欢迎指正
在此附上代码资源

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于HAL库stm32f1的DS18B20温度传感器 的相关文章

  • 专访用自己姓氏命名编译器YC++的创始人

    在CSDN的论坛里看到了这样的一条帖子 请使用中国人开发的C C 编译器 网页浏览器内核 并提供了该软件的下载地址 从大家的跟帖来看很多人 是很有兴趣的 但是作者并没有留下太多的介绍说明类的文字 为了一探究竟 我拨通了作者留下的电话并完成了

随机推荐

  • Ubuntu 16.04设置root用户登录图形界面

    Ubuntu默认的是root用户不能登录图形界面的 只能以其他用户登录图形界面 这样就很麻烦 因为权限的问题 不能随意复制删除文件 用gedit编辑文件时经常不能保存 只能用vim去编辑 下面以Ubuntu 16 04版为例说明 1 打开终
  • STM32实战项目:HAL_RCC_OscConfig中程序卡死问题解决办法

    STM32实战项目经验 HAL RCC OscConfig中程序卡死问题解决办法 工程环境 STM32CUBEIDE STM32F405VG 现象复现 项目中一个是IAP程序 另一个是APP程序 两个程序都是使用STM32CubeIDE生成
  • 搜索题目综合

    BFS 1 小X学游泳 题解 枚举每一个点作为连通块的起点 求得连通块大小 然后打擂台求最值即可 参考代码 include
  • element-ui和element-plus的自定义列表格用法

    前言 element plus 这个 UI 组件库 虽说基本和 vue2 element ui 差不多 但还是有点区别 以至于按emenent ui的写法来写会发现报错 下面我将讲解一下element ui和element plus的自定义
  • 一文彻底讲清Linux tty子系统架构及编程实例

    摘要 本文详细解读了linux系统下的tty子系统的深层次原理和架构 并参考了LDD3中的代码实例讲述了无硬件下实现一个简单的tty设备驱动模块的编写 对了解tty子系统及下部串口驱动模块的学习有较好的参考价值 1 tty设备简介 tty一
  • 抖音广告IOS/Android接入笔记:

    一 抖音广告接入 Android接入 注意 内容输出对接中已包含广告对接 建议使用广告4 6 0 7版本 如使用其他广告版本建议做好自测 2600及以上版本 需要使用如下Maven命令 火山引擎maven仓库地址 maven url htt
  • 红帽系统服务器格式化,Redhat Linux默认的文件系统是什么格式?

    满意答案 现在Redhat Linux默认的文件系统格式是ext4 可以通过如下多种方法查询文件系统类型 1 mount mount dev sda1 on type ext4 rw errors remount ro user xattr
  • 第五周总结

    已知字符串 this is a test of java 按要求执行以下操作 统计该字符串中字母s出现的次数 统计该字符串中子串 is 出现的次数 统计该字符串中单词 is 出现的次数 实现该字符串的倒序输出 public class da
  • MySQL之常见的CRUD面试题【下】

    Welcome Huihui s Code World 接下来看看由辉辉所写的关于MySQL数据库的相关操作吧 目录 Welcome Huihui s Code World 导读 一 MySQL常见的内置函数 1 字符串函数 2 数值函数
  • 测绘地理信息标准规范汇总下载

    经常 我们要下载一些相关的规范来指导作业 每次都在网上找 这里一次性全部整理好 欢迎大家来下载 打包下载 链接 百度网盘地址 分页下载 一 国家测绘局制定的测绘地理信息国家标准 专题地图信息分类与代码 GBT 18317 2001 被GBT
  • 4-C语言-冒泡排序以及数组名的使用

    问题 给数组进行从小到大的升序排序 思想 一般给冒泡排序 进行封装 写成一个函数 这就需要让数组传进去 而传数组 实际传的数组的首元素的地址 因此如果在冒泡内部 进行数组数据个数的计算 用sizeof a sizeof a 0 实际上为1
  • Braft--工作日记

    建议在阅读本笔记之前先观看此网址的动画Raft 分布式共识算法动画演示 首先bRaft是实现分布式共识的协议 一个节点可以处于三种状态 Follower跟随者状态 Candidate候选者状态 Leader领导者状态 而所有的节点都以跟随者
  • 计算机毕业设计SSM大型零售电商平台——购物车管理子系统【附源码数据库】

    项目运行 环境配置 Jdk1 8 Tomcat7 0 Mysql HBuilderX Webstorm也行 Eclispe IntelliJ IDEA Eclispe MyEclispe Sts都支持 项目技术 SSM mybatis Ma
  • softmax函数的定义及求导

    本文中 x0 x1 xm x 0 x 1 x m 代表一个向量 也就是一个 m m行1列的矩阵 在监督式的深度学习中 输入通常是一个向量 用xx表示 输出 y y则可以分为多种情况 标量 yy表示输入 x x属于某一类别的概率 向量 此时输
  • AutoDev 1.1.3 登场,个性化 AI 辅助:私有化大模型、自主设计 prompt、定义独特规则...

    在过去的半个月里 我们为开源辅助编程工具 AutoDev 添加了更强大的自定义能力 现在你可以 使用自己部署的开源大模型 自己配置 Intellij IDEA 中的行为 自定义开发过程中的规范 当然了 如果您自身拥有开发能力的话 建议您自己
  • 绕过身份检测,破解Android SU

    http www 61ic com Mobile Android 201207 43661 html 由于Android底层是Linux内核 故了解了Linux的权限管理后就可以知道ROOT的原理 具体可以访问 Android系统权限和ro
  • js基础-语句

    语句 表达式在JavaScript中是短语 而语句 statement 就是JavaScript整句或命令 JavaScript语句是以分号结束 默认情况下 JavaScript解释器依照语句的编写顺序依次执行 1 表达式语句 1 复合语句
  • linux服务器部署docker版nginx(nginx容器化)

    为了服务器安全 nginx端口不直接暴漏在外 现在服务器使用了docker版nginx 记录下使用步骤 docker安装就不再叙述 之前有写 分为2种适用于服务器能上网和不能上网的情况 这里写的一个sh文件和dockerfile文件 用于d
  • 最强大的布局——约束布局(ConstraintLayout)的一些技巧

    一 使用viewBinding 1 想开启那个模块的viewBinding就进入对应模块的build gradle 2 进入app的build gradle 开启viewbinding viewBinding enabled true 3
  • 基于HAL库stm32f1的DS18B20温度传感器

    由于做比赛 所以写了温度传感器 记录一下 一 介绍 DS18B20是常用的数字温度传感器 其输出的是数字信号 具有体积小 硬件开销低 抗干扰能力强 精度高的特点 1 DS18B20数字温度传感器接线方便 封装成后可应用于多种场合 如管道式