普中51单片机:DS18B20温度传感器操作指南(十三)

news2024/9/23 17:20:15

在这里插入图片描述

文章目录

  • 引言
  • 电路图
  • 引脚讲解
  • 初始化时序
  • 写时序
  • 读时序
  • 温度变换
  • 温度读取
  • 完整代码

引言

DS18B20是一款单总线接口的数字温度传感器,仅需一个IO口即可实现数据通信。这里只对如何简单操作开发板的DS1802进行讲解,关于DS18B20温度传感器的详细操作原理,可参考此博客:DS18B20数字温度传感器操作解析。

电路图

下图显示了DS18B20的电路连接。数据总线通过J14排针引出,并连接到所选的IO口。数据总线上需要一个上拉电阻以确保稳定的通信。
在这里插入图片描述

引脚讲解

DS18B20传感器通常采用TO-92封装或PDIP封装,具有以下三个主要引脚:

  • VDD - 电源正极,为传感器提供工作电压。
  • GND - 电源负极,接地。
  • DQ - 数据引脚,用于与微控制器或计算机进行数据通信。

引脚详解

  1. VDD: 连接到传感器的工作电压,通常为3.3V或5V。确保不要超过传感器的最大工作电压,以避免损坏。
  2. GND: 连接到电路的地线,确保传感器的稳定工作。
  3. DQ: 是一个开漏输出引脚,需要通过上拉电阻连接到VDD。这个引脚负责与主控制器进行通信,支持1-Wire通信协议。

初始化时序

初始化过程从主机发送复位脉冲开始。主机将总线拉低至少480微秒(us),通常是500us,以确保所有从设备都能检测到复位信号。复位脉冲后,总线需保持高电平15-60微秒,等待从设备响应。

从设备通过发送存在脉冲来响应,表示它们已经检测到复位信号,并将总线拉低60-240微秒。表明它已检测到复位信号。之后将电平拉高。
在这里插入图片描述

sbit DS18B20_DQ = P3^7;

unsigned char DS18B20_Init()
{
	
	unsigned char i;
	unsigned char ackBit;

	DS18B20_DQ = 1;
	DS18B20_DQ = 0;
	i = 247;
	while (--i);	 //延时500us
	DS18B20_DQ = 1;
	i = 32;
	while (--i);
	ackBit = DS18B20_DQ;
	i = 247;
	while (--i);	 //延时500us
	return ackBit;
}

写时序

写时序包括主机发送数据位“0”或“1”到从设备。每个位的写入时序稍有不同。每次写入一个数据位都需要初始化一个写周期。主机将总线拉低至少1微秒(通常是1-15微秒),然后释放总线,这是初始化写周期。

写0时序:

  • 主机将总线拉低至少60微秒(通常是60-120微秒),然后释放总线。

写1时序:

  • 主机将总线拉低至少1微秒(通常是1-15微秒),然后在剩余时间内保持高电平(释放总线)。

写入一个字节(8位)需要重复上述写0和写1时序八次。写入顺序为低位在前(LSB first)。

  1. 开始写入字节:初始化第一个写周期。
  2. 写入每个位:根据数据位的值,执行写0或写1时序。
  3. 结束写入字节:完成8个位的写入后,字节写入结束。

假设我们要写入字节0x5A(01011010)。

  • 写入0位:主机将总线拉低至少60微秒,释放总线。
  • 写入1位:主机将总线拉低至少1微秒,释放总线。
  • 写入0位:重复写0时序。
  • 写入1位:重复写1时序。
  • 写入1位:重复写1时序。
  • 写入0位:重复写0时序。
  • 写入1位:重复写1时序。
  • 写入0位:重复写0时序。

在这里插入图片描述

//发送一位
void ds18b20_write_bit(unsigned char bits)
{ 
	unsigned char i;
	DS18B20_DQ = 0;
	i = 4;
	while (--i); //延时10us
	DS18B20_DQ = bits;
	i = 24;
	while (--i); //延时50us
	DS18B20_DQ = 1;
}

//发送字节
void ds18b20_write_byte(unsigned char byte)
{
	unsigned char i;
	for(i = 0;i<8;i++)
	{
		ds18b20_write_bit(byte & 0x01<<i);//先发送低位
	}
}

读时序

每次读取一个数据位都需要初始化一个读周期。初始化读周期期间需要主机将总线拉低至少1微秒(通常是1-15微秒),然后释放总线。之后读取数据位,主机在读周期内读取从设备发送的数据位。需要主机将总线拉低至少1微秒(通常是1-15微秒)。然后释放总线,主机释放总线,并在15微秒内读取总线状态。读取数据位期间如果总线保持低电平,读取到的数据位为0;如果总线拉高,读取到的数据位为1。要读取一个字节(8位),需要重复上述读取数据位的过程八次,按低位在前(LSB first)的顺序读取。

假设我们要读取一个字节的数据,具体步骤如下:

  1. 初始化读周期:主机将总线拉低至少1微秒,然后释放总线。
  2. 读取每个位:在读周期内,主机读取从设备发送的每个位数据。
  3. 完成字节读取:重复上述步骤八次,读取一个完整的字节。

在这里插入图片描述

//接收一位
unsigned char ds18b20_read_bit()
{ 
	unsigned char i;
	unsigned char bits;
	DS18B20_DQ = 0;
	i = 2;
	while (--i); //延时5us
	DS18B20_DQ = 1;
	i = 2;
	while (--i); //延时5us
	bits = DS18B20_DQ;
	i = 24;
	while (--i); //延时50us
	return bits;
}

unsigned char ds18b20_read_byte()
{
	unsigned char i;
	unsigned char byte = 0x00;
	for(i = 0;i<8;i++)
	{
		if(ds18b20_read_bit())
		{
			byte |= 0x01<<i;	
		}
	}
	return byte;	
}

温度变换

DS18B20温度传感器的温度转换功能允许用户读取精确的温度数据。为了实现温度转换,必须遵循特定的时序和命令流程。

温度转换流程包括以下几个主要步骤:

  1. 发送初始化命令:主机需要发送初始化命令来复位总线并检测从设备的存在。
  2. 跳过ROM命令:向总线上的所有设备广播命令。所有设备都会响应接下来的命令。
  3. 发送启动温度转换命令:0x44用于启动温度转换(Convert T)

在这里插入图片描述

//转换温度
void ds18b20_ConvertT()
{
	DS18B20_Init();
	ds18b20_write_byte(0xCC);
	ds18b20_write_byte(0x44);
}

温度读取

读取DS18B20温度传感器的数据是一个包括命令发送和数据处理的过程。

温度读取过程包括以下几个主要步骤:

  1. 发送初始化命令:主机需要发送初始化命令来复位总线并检测从设备的存在。
  2. 跳过ROM命令:向总线上的所有设备广播命令。所有设备都会响应接下来的命令。
  3. 发送读暂存器命令:用于从DS18B20传感器的暂存器中读取温度数据、报警阈值和配置寄存器信息。

在这里插入图片描述
先读取低位,后读取高位,温度数据是16位带符号的二进制数,最低位代表 2 − 4 2^{-4} 24摄氏度(即0.0625摄氏度)

//读取温度
float ds18b20_ReadT()
{
	unsigned char byteL;
	unsigned char byteH;
	int temp;
	float T;
	DS18B20_Init();
	ds18b20_write_byte(0xCC);
	ds18b20_write_byte(0xBE);
	byteL = ds18b20_read_byte();//低字节
	byteH = ds18b20_read_byte();//高字节
	temp = (byteH << 8) | byteL;
	T = temp / 16.0;
	return T;
}

完整代码

LCD1602液晶显示屏实时获取温度变化

#include <REGX52.H>
#include <LCD1602.H>
#include "stdio.h"
sbit DS18B20_DQ = P3^7;

unsigned char DS18B20_Init()
{
	unsigned char i;
	unsigned char ackBit;

	DS18B20_DQ = 1;
	DS18B20_DQ = 0;
	i = 247;
	while (--i);	 //延时500us
	DS18B20_DQ = 1;
	i = 32;
	while (--i);
	ackBit = DS18B20_DQ;
	i = 247;
	while (--i);	 //延时500us
	return ackBit;
}

//发送一位
void ds18b20_write_bit(unsigned char bits)
{ 
	unsigned char i;
	DS18B20_DQ = 0;
	i = 4;
	while (--i); //延时10us
	DS18B20_DQ = bits;
	i = 24;
	while (--i); //延时50us
	DS18B20_DQ = 1;
}

//接收一位
unsigned char ds18b20_read_bit()
{ 
	unsigned char i;
	unsigned char bits;
	DS18B20_DQ = 0;
	i = 2;
	while (--i); //延时5us
	DS18B20_DQ = 1;
	i = 2;
	while (--i); //延时5us
	bits = DS18B20_DQ;
	i = 24;
	while (--i); //延时50us
	return bits;
}

//发送字节
void ds18b20_write_byte(unsigned char byte)
{
	unsigned char i;
	for(i = 0;i<8;i++)
	{
		ds18b20_write_bit(byte & 0x01<<i);//先发送低位
	}
}

unsigned char ds18b20_read_byte()
{
	unsigned char i;
	unsigned char byte = 0x00;
	for(i = 0;i<8;i++)
	{
		if(ds18b20_read_bit())
		{
			byte |= 0x01<<i;	
		}
	}
	return byte;	
}

//转换温度
void ds18b20_ConvertT()
{
	DS18B20_Init();
	ds18b20_write_byte(0xCC);
	ds18b20_write_byte(0x44);
}

//读取温度
float ds18b20_ReadT()
{
	unsigned char byteL;
	unsigned char byteH;
	int temp;
	float T;
	DS18B20_Init();
	ds18b20_write_byte(0xCC);
	ds18b20_write_byte(0xBE);
	byteL = ds18b20_read_byte();//低字节
	byteH = ds18b20_read_byte();//高字节
	temp = (byteH << 8) | byteL;
	T = temp / 16.0;
	return T;
}

unsigned char ack = 1;

float g_T;

void main()
{
	char temp_buff[50];
	LCD_Init();
	LCD_ShowString(1,1,"helloworld");
	ack = DS18B20_Init();
	LCD_ShowNum(2,1,ack,3);
	while(1)
	{
		ds18b20_ConvertT();
		g_T = ds18b20_ReadT();
		if(g_T<0)
		{
			//负数
			LCD_ShowChar(2,1,'-');
			g_T = -g_T;
		}
		else
		{
			LCD_ShowChar(2,1,'+');
		}
	    // 使用 sprintf 将浮点数转换为字符串
	    sprintf(temp_buff, "%.3f", g_T);
		LCD_ShowString(2,2,temp_buff);
	}
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

矢量文件坐标转换:2000坐标系转换为wgs84坐标系,具体代码实现

最近在处理矢量样本的时候&#xff0c;遇到一些shp文件的坐标系为2000坐标&#xff0c;需要统一地把非WGS84坐标系的矢量转换为WGS84坐标系。 本文记录一下如何进行2000坐标系转化为wgs84坐标系的过程。 在处理矢量数据转换的过程中&#xff0c;有几个关键步骤确保了数据的有效…

ComfyUI LoRA应用和三级放大

ComfyUI LoRA应用和三级放大 LoRA加载器LoRA应用三级放大 LoRA加载器 新建节点–>加载器–>LoRA加载器 LoRA应用 如下图串起来 三级放大

ActiveMQ任意文件写入漏洞(CVE-2016-3088)复现

一.环境配置 腾讯云的ubuntu操作系统&#xff0c;已经安装有docker 和 vulhub 直接来到 启动环境docker-compose&#xff0c;要在root权限下运行。 docker-compose up -d 若出现等待时间过长的情况&#xff0c;请参考这篇文章http://t.csdnimg.cn/SYhbE 访问http://公网ip:8…

Vivado启用modelsim报错boost::filesystem::remove

问题描述 在vivado中以配置好仿真工具为modelsim&#xff0c;但是启动仿真时报错如下&#xff1a; boost::filesystem::remove: 另一个程序正在使用此文件&#xff0c;进程无法访问。 "C:/Users/ZYP_PC/Desktop/verilog_test/simulation_project/project_1/project_1.si…

VTK8.2.0编译(Qt 5.14.2+VS2017)

VTK8.2.0编译(Qt 5.14.2+VS2017) 关于Qt和MSVC的安装,可以参考文章(Qt+MSVC2017)。 本篇VTK在Qt+MSVC的配置下的编译。VTK 以8.2.0为例。 一、环境变量的配置 我们打开电脑的环境变量,可以看到没有Qt相关的路径的配置: 我们把Qt相关的变量增加一下(主要以64位为主,…

day02-员工管理、Swapper测试、JWT、ThreadLocal、全局时间转换

苍穹外卖-day02 课程内容 新增员工员工分页查询启用禁用员工账号编辑员工导入分类模块功能代码 **功能实现&#xff1a;**员工管理、菜品分类管理。 员工管理效果&#xff1a; 菜品分类管理效果&#xff1a; 1. 新增员工 1.1 需求分析和设计 1.1.1 产品原型 一般在做需求…

LNMP环境搭建论坛

注意&#xff1a;这里用的是Rocky Linux自带的Nginx 1.1 环境准备 1.1.1 安装部署Nginx、MySQL和PHP相关组件 [rootRocky8-node1 ~]# yum install nginx php-mysqlnd php php-gd php-fpm php-xml mysql-server -y 1.1.2 启动服务 [rootRocky8-node1 ~]# systemctl enable …

【C++】C++入门基础【类与对象】

目录 1.类 1.1类的定义 1.2struct 与 class对比 2.访问限定符 3. 类域 4.实例化 5.存储大小----内存对齐 6.this指针 1.类 1.1类的定义 class作为类的关键字&#xff0c;后面跟的是类的名字&#xff0c;如Stack&#xff0c;{}中的为类的主体&#xff0c;类定义结束时…

cpp笔记07:STL

STL 基本概念 STL&#xff08;Standard Template Library&#xff0c;标准模板库&#xff09; STL从广义上分为&#xff1a;容器&#xff08;container&#xff09;算法&#xff08;algorithm&#xff09;迭代器&#xff08;iterator&#xff09; 容器和算法之间通过迭代器…

8.7 Day15 匿名用户访问FTP与日志查看

查看配置文件 vsftpd是一个认证文件&#xff0c;意味着ftp是通过vsftpd这个认证文件来对我们输入的用户名和密码进行认证的&#xff0c;那么这个认证文件在哪里呢&#xff1f; 所在位置如下&#xff1a; 查看文件配置内容 默认通过系统来验证&#xff0c;但现在我们欲做一个类…

web自动化7-pytest④实践测试用例-回归用例web自动化部分代码

文档说明: 本文档包括web自动化目录结构代码元素定位 : 父级, 同级后面, 同级div, 包含, 不包含, 鼠标右键, 悬停, 句柄切换(浏览器切换,关闭), 不可见元素查找, 滑动到不可见元素出现, 悬停后点击, 页面有值判断, 页面数据量判断web自动化: 前置, 后置事件 结合上篇文章, 基本…

Django—模板继承和包含

模块的继承意义&#xff1a;将需要多次用到的内容&#xff08;盒子&#xff09;进行引用&#xff0c;减少代码的重复使用 如我们经常在网上看见的导航栏&#xff0c;页脚等 第一步&#xff1a;我们将继承模块写在一个html文件里面 第二步&#xff1a;创建一个html文件&#x…

【归并排序/快排/堆排序】912. 排序数组

力扣连接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 归并排序 对左右子集合分别排序&#xff0c;然后合并两个有序数组 class Solution {int[] nums;public int[] sortArray(int[] nums) {this.nums nums;return sort(0, nums.length-1);}int[] sort(int st, i…

电机学前置知识

https://zhuanlan.zhihu.com/p/712393024 基本定律 全电流定律&#xff08;安培环路定律&#xff09; 在磁场中沿任意闭合回路磁场强度的线积分等于穿过该回路所有电流的代数和&#xff0c;即&#xff1a; ∮ H ⋅ d l ∮ J ⋅ d s \oint H \cdot dl \oint J \cdot ds ∮H…

Windows 11下RTX 4090深度学习及大模型微调环境安装指南

在安装深度学习及大模型微调环境时&#xff0c;经历了多次反复操作&#xff08;如CUDA、cuDNN、PyTorch的安装与卸载&#xff09;。为了避免走弯路&#xff0c;总结了以下步骤&#xff1a; 步骤 1&#xff1a;显卡驱动安装 首先在安装完Windows 11后&#xff0c;安装RTX 4090显…

C++——类模板经典案例——自定义通用数组类

案例&#xff1a;自定义数组类 需求&#xff1a; 1&#xff0c;对内置数据及自定义数据类型的数据存储 2&#xff0c;将数组中的数据存储到堆区 3&#xff0c;构造函数中可以存入数组的容量 4&#xff0c;提供对应的拷贝构造函数和运算符重载防止浅拷贝问题的发生 5&#xff0c…

户外上网黑科技|300~500元随身wifi测评推荐,华为vs格行vs中兴vs上赞,哪个好?

1.老牌国货&#xff0c;颜值担当——华为 设备价格&#xff1a;499元 套餐价格&#xff1a;99一个月 599一年 质保时间&#xff1a;1年 测评&#xff1a;网速大概在50~60M/S&#xff0c;华为是老牌国货了&#xff0c;设备上没有硬伤&#xff0c;家里连接多设备都没什么问…

小怡分享之Java中的异常

前言&#xff1a; &#x1f308;✨之前小怡带大家认识了String类&#xff0c;今天小怡给大家分享Java中的异常。 1.异常的概念与体系结构 1.1 异常的概念 在日常开发中&#xff0c;绞尽脑汁将代码写的尽善尽美&#xff0c;在程序运行中&#xff0c;难免会出现一些奇奇怪怪…

Python学习(2):在单机机器学习,使用Dask实现鸢尾数据集 Iris 的分类任务

目录 一、源码来源 二、鸢尾花数据集的品种分类 1、数据处理步骤 &#xff08;1&#xff09;数据集加载 &#xff08;2&#xff09;准备特征和标签 &#xff08;3&#xff09;训练集和测试集划分 2、安装必需的软件包 3、运行程序 三、信用卡欺诈数据集检测信用卡交易…

全网最详细的LVS实战详解

一、Lvs-nat实战部署 1、准备 设置好网卡信息 2、基础环境搭建详情 ①调度器LVS:网卡ens160(NAT模式)、网卡ens224(仅主机模式)&#xff0c;使其可处于不同的VLAN段 为网卡ens160设置IP vmset.sh ens160 172.25.254.100 lvs.zf.org为网卡ens224设置IP vmset.sh ens224 192.…