51单片机DS18B20的使用
文章目录
- 前言
- 一、DS18B20介绍
- 二、单总线协议
- 三、DS18B20引脚说明
- 四、DS18B20程序编写
- 1.DS18B20复位函数
- 2.DS18B20存在检测
- 3.DS18B20读取一个bit和一个byte函数
- 4.DS18B20写一个字节函数
- 5.开始温度转换函数
- 6.DS18B20初始化函数
- 7.DS18B20读取温度函数
- 五、代码测试
- 总结
前言
本篇文章将带大家学习DS18B20的使用,并将DS18B20显示到数码管中。
一、DS18B20介绍
DS18B20是一种数字温度传感器,可直接将温度转换为数字信号输出。它是一种高精度、低功耗、单总线温度传感器,具有以下特点:
精度高:DS18B20的温度测量精度为±0.5℃,可满足大多数应用的需求。
低功耗:DS18B20的工作电压范围为3V-5.5V,工作电流仅为1mA,非常适合应用于低功耗设备中。
单总线协议:DS18B20采用单总线协议,只需要一条数据线即可实现数据传输和电源供应,简化了电路设计。
高精度:DS18B20内置16位ADC,可以在-55℃到+125℃的温度范围内进行测量,且具有高抗干扰性能。
体积小:DS18B20的封装形式为TO-92、TO-92S、SOT-223等,体积小巧,方便集成到各种应用中。
DS18B20应用广泛,可用于温度测量、温度控制、温度报警等各种场合。常见的应用包括室内温度控制、电子温度计、冰箱温度监测、工业自动化等。由于其低功耗、高精度、体积小等特点,DS18B20在物联网等领域也得到了广泛应用。
二、单总线协议
单总线协议是一种串行通信协议,它可以通过一根线实现数据传输和电源供应。在单总线协议中,数据和时钟信号共用一根线,因此只需要一条线就可以实现数据传输和设备控制,简化了电路设计,降低了成本。
在单总线协议中,每个设备都有一个唯一的地址,通过地址可以对设备进行选择。当主设备需要与从设备通信时,它会向总线上发送一个请求信号,同时指定通信的从设备地址。从设备接收到请求信号后,会向总线上发送应答信号,并在一段时间内提供数据。主设备在接收到应答信号后,就可以接收从设备提供的数据。
在单总线协议中,数据的传输速率较慢,一般在几千位每秒到几十万位每秒之间。因此,它主要应用于一些对通信速度要求不高的场合,例如温度传感器、湿度传感器等。同时,单总线协议具有低成本、低功耗、可靠性高等优点,在物联网、家庭自动化等领域也得到了广泛的应用。
这里我们使用的DS18B20所使用的就是单总线协议。
三、DS18B20引脚说明
DS18B20只需要三个引脚即可读取温度数据。
接线方式
GND-----51单片机的GND
VDD-----51单片机的电源引脚
DQ-------数据的读取和写入引脚

四、DS18B20程序编写
1.DS18B20复位函数


/*******************************************************************************
* 函 数 名 : ds18b20_reset
* 函数功能 : 复位DS18B20
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void ds18b20_reset(void)
{DS18B20_PORT=0; //拉低DQdelay_10us(75); //拉低750usDS18B20_PORT=1; //DQ=1delay_10us(2); //20US
}
2.DS18B20存在检测

首先需要等待一个低电平,当等待到低电平后就等待一个高电平,当同时满足这两个条件时就说明DS18B20是存在的。
/*******************************************************************************
* 函 数 名 : ds18b20_check
* 函数功能 : 检测DS18B20是否存在
* 输 入 : 无
* 输 出 : 1:未检测到DS18B20的存在,0:存在
*******************************************************************************/
u8 ds18b20_check(void)
{u8 time_temp=0;while(DS18B20_PORT&&time_temp<20) //等待DQ为低电平{time_temp++;delay_10us(1); }if(time_temp>=20)return 1; //如果超时则强制返回1else time_temp=0;while((!DS18B20_PORT)&&time_temp<20) //等待DQ为高电平{time_temp++;delay_10us(1);}if(time_temp>=20)return 1; //如果超时则强制返回1return 0;
}
3.DS18B20读取一个bit和一个byte函数
DS18B20通过使用时间片来读出和写入DS18B20数据。详细介绍如下。



根据上面的讲解我们可以写出读一个bit的函数出来。
读取一个位函数
/*******************************************************************************
* 函 数 名 : ds18b20_read_bit
* 函数功能 : 从DS18B20读取一个位
* 输 入 : 无
* 输 出 : 1/0
*******************************************************************************/
u8 ds18b20_read_bit(void)
{u8 dat=0;DS18B20_PORT=0;_nop_();_nop_();DS18B20_PORT=1; _nop_();_nop_(); //该段时间不能过长,必须在15us内读取数据if(DS18B20_PORT)dat=1; //如果总线上为1则数据dat为1,否则为0else dat=0;delay_10us(5);return dat;
}
读取一个字节函数其实就是循环8次读取bit将8个bit组合成一个byte。
这里特别要注意的就是每次读取一位,且先读低位再读高位。
读取一个字节函数
/*******************************************************************************
* 函 数 名 : ds18b20_read_byte
* 函数功能 : 从DS18B20读取一个字节
* 输 入 : 无
* 输 出 : 一个字节数据
*******************************************************************************/
u8 ds18b20_read_byte(void)
{u8 i=0;u8 dat=0;u8 temp=0;for(i=0;i<8;i++)//循环8次,每次读取一位,且先读低位再读高位{temp=ds18b20_read_bit();dat=(temp<<7)|(dat>>1);}return dat;
}
4.DS18B20写一个字节函数


/*******************************************************************************
* 函 数 名 : ds18b20_write_byte
* 函数功能 : 写一个字节到DS18B20
* 输 入 : dat:要写入的字节
* 输 出 : 无
*******************************************************************************/
void ds18b20_write_byte(u8 dat)
{u8 i=0;u8 temp=0;for(i=0;i<8;i++)//循环8次,每次写一位,且先写低位再写高位{temp=dat&0x01;//选择低位准备写入dat>>=1;//将次高位移到低位if(temp){DS18B20_PORT=0;_nop_();_nop_();DS18B20_PORT=1; delay_10us(6);}else{DS18B20_PORT=0;delay_10us(6);DS18B20_PORT=1;_nop_();_nop_(); } }
}
5.开始温度转换函数

/*******************************************************************************
* 函 数 名 : ds18b20_start
* 函数功能 : 开始温度转换
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void ds18b20_start(void)
{ds18b20_reset();//复位ds18b20_check();//检查DS18B20ds18b20_write_byte(0xcc);//SKIP ROMds18b20_write_byte(0x44);//转换命令
}
6.DS18B20初始化函数
初始化是非常简单的我们只需要使用之前编写好的函数,首先将DS18B20复位,然后检查DS18B20是否存在。
/*******************************************************************************
* 函 数 名 : ds18b20_init
* 函数功能 : 初始化DS18B20的IO口 DQ 同时检测DS的存在
* 输 入 : 无
* 输 出 : 1:不存在,0:存在
*******************************************************************************/
u8 ds18b20_init(void)
{ds18b20_reset();return ds18b20_check();
}
7.DS18B20读取温度函数
在DS18B20中,温度数据是以16位的方式存储的,分为高8位和低8位。因此,在读取温度数据时,需要先读取低8位数据,再读取高8位数据,然后将它们合并为16位数据。

通过这里我们可以知道正温度的符号位和负温度的符号位是不相同的。所以下面我们需要判断读取出来的温度是正温度还是负温度。
/*******************************************************************************
* 函 数 名 : ds18b20_read_temperture
* 函数功能 : 从ds18b20得到温度值
* 输 入 : 无
* 输 出 : 温度数据
*******************************************************************************/
float ds18b20_read_temperture(void)
{float temp;u8 dath=0;u8 datl=0;u16 value=0;ds18b20_start();//开始转换ds18b20_reset();//复位ds18b20_check();//检测是否存在DS18B20ds18b20_write_byte(0xcc);//SKIP ROMds18b20_write_byte(0xbe);//读存储器datl=ds18b20_read_byte();//低字节dath=ds18b20_read_byte();//高字节value=(dath<<8)+datl;//合并为16位数据if((value&0xf800)==0xf800)//判断符号位,负温度{value=(~value)+1; //数据取反再加1temp=value*(-0.0625);//乘以精度 }else //正温度{temp=value*0.0625; }return temp;
}
五、代码测试
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{ u8 i=0;int temp_value;u8 temp_buf[5];ds18b20_init();//初始化DS18B20while(1){ i++;if(i%50==0)//间隔一段时间读取温度值,间隔时间要大于温度传感器转换温度时间temp_value=ds18b20_read_temperture()*10;//保留温度值小数后一位if(temp_value<0)//负温度{temp_value=-temp_value;temp_buf[0]=0x40;//显示负号 }elsetemp_buf[0]=0x00;//不显示temp_buf[1]=gsmg_code[temp_value/1000];//百位temp_buf[2]=gsmg_code[temp_value%1000/100];//十位temp_buf[3]=gsmg_code[temp_value%1000%100/10]|0x80;//个位+小数点temp_buf[4]=gsmg_code[temp_value%1000%100%10];//小数点后一位smg_display(temp_buf,4);}
}
总结
DS18B20的总结和驱动代码编写就到这里了,希望大家下去自己能够多看数据手册多多总结经验。
相关文章:
51单片机DS18B20的使用
文章目录前言一、DS18B20介绍二、单总线协议三、DS18B20引脚说明四、DS18B20程序编写1.DS18B20复位函数2.DS18B20存在检测3.DS18B20读取一个bit和一个byte函数4.DS18B20写一个字节函数5.开始温度转换函数6.DS18B20初始化函数7.DS18B20读取温度函数五、代码测试总结前言 本篇文…...
Vue组件原理知识(1)
Vue 组件知识整理(1)文章目录Vue 组件知识整理(1)一、组件介绍1.1 传统方式与组件方式编写应用对比二、组件使用2.1 非单文件组件的使用**1. 组件的创建****2. 组件的注册****3. 组件的使用****4. Vue中使用组件的三大步骤总结***…...
Linux:IO库函数
目录标准库IO函数一、fopen二、fwrite三、fread四、fseek五、fclose在编写程序时,离不开IO操作,最常见的IO操作就是用printf函数进行打印,本文主要介绍的是封装后的IO库函数。 标准库IO函数 常使用的IO库函数如下: 函数作用fop…...
Go爬虫学习笔记
N002.02 Go分布式爬虫实战 开篇 学习三阶段 入门,照猫画虎底层,了解方方面面,深入阅读源码和书籍借助开源组件来进行复杂设计,窥探各个组件赋能业务 分布式系统: 扩展性一致性可用性高并发微服务 爬虫࿱…...
数据结构课程设计:高铁信息管理系统(C++实现)
目录 简介实验输出实验要求代码运行环境结语简介 Hello! 非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出~ ଘ(੭ˊᵕˋ)੭ 昵称:海轰 标签:程序猿|C++选手|学生 简介:因C语言结识编程,随后转入计算机专业,获得过国家奖学金,有幸在竞赛中拿过一些国奖…...
Python 模块之 datetime
datetime 对象格式化为字符串 标准转换格式符号: %a 本地星期的短名称 如:Sun, Mon, ..., Sat (en_US); So, Mo, ..., Sa (de_DE) %A 本地星期全名称 如 :Sunday, Monday, ..., Saturday (en_US);Sonntag, Montag, ..., Samstag (de_DE) %w…...
linux安装编译ffmpeg
ffmpeg下载:http://ffmpeg.org/releases可以下载适合自己的版本。我下载的是5.0版本,然后解压:tar xvf ffmpeg-5.0.tar.gz进入ffmpegcd ffmpeg-5.0编译ffmpeg./configure --prefix/root/ffmpeg //编译文件存放的路径如果是交叉编译添加以下参…...
嵌入式Linux驱动开发(二)LED驱动
1. Linux下LED驱动原理 与裸机区别在于,编写驱动要符合linux驱动框架规范。裸机直接对寄存器物理地址进行读写,linux下需要经过MMU。 1.1 地址映射相关概念 1)MMU(Memory Manage Unit - 内存管理单元): …...
C++学习
强制转换运算符 C 引入了四种不同的强制转换运算符以进行强制转换: const_caststatic_castreinterpret_castdynamic_cast C语言强制类型转换缺点: 主要是为了克服C语言强制类型转换的以下三个缺点。 没有从形式上体现转换功能和风险的不同。 例如&am…...
JavaEE简单示例——依赖注入
简单介绍: 首先我们要知道,依赖注入就是赋值,带着这句话去理解依赖注入就非常的简单了,将文中所有的依赖注入全部脑部替换成给属性赋值,再去理解依赖注入的概念。 依赖注入(DI)是指IoC容器在运…...
大数据框架之Hive: 第7章 综合案例练习(初级)
第7章 综合案例练习(初级) 一 环境准备 1.1 建表语句 hive> -- 创建学生表 DROP TABLE IF EXISTS student; create table if not exists student_info(stu_id string COMMENT 学生id,stu_name string COMMENT 学生姓名,birthday string COMMENT 出…...
kafka:linux 安装 kafka集群
kafka运行依赖于 jdk、zookeeper,kafka可视化工具选择kafka-eagle。所以要装的组件有:jdk、zookeeper、kafka、kafka-eagle一、安装jdk下载linux版本的jdk包,比如:jdk-8u192-linux-x64.tar.gz。将其复制到 /opt 目录下并解压&…...
springboot实现Hessian协议的RPC服务
背景 这段时间在公司接手了一个新项目,看到一段代码非常奇怪的,研究了好久。内容大概是这样 public void getUser (int id) {userService.getById(id); }当我点击这个方法进去的时候,我发现这个UserService类居然是导入jar包的一个接口&…...
2-6 SpringCloud快速开发入门: Eureka 服务注册中心发现与消费服务
接上一章节向Eureka 服务注册中心注册服务,这里讲讲Eureka 服务注册中心发现与消费服务 Eureka 服务注册中心发现与消费服务 我们已经搭建一个服务注册中心,同时也向这个服务注册中心注册了服务,接下来我们就可以发现和消费服务了࿰…...
Java-Web之s2-001与CommonsCollections
本文源自我个人入坑Java-Web安全的一点小经验,献给那些看得懂java代码但不知道从哪里入手代审的师傅们:) Struts2之s2-001 环境配置 说说环境配置的问题,大多数人对漏洞复现的恐惧感还是来自于环境的配置,也许配了大…...
【JavaSE】数组的定义和使用(下)
数组的定义和使用(下)4. 数组练习4.1 模拟实现toString4.2 数组拷贝4.3 比较两个数组是否相同4.4 填充数组4.3 求数组中元素的平均值4.4 查找数组中指定元素(顺序查找)4.5 查找数组中指定元素(二分查找)4.6…...
Oracle 实现对全局错误语句的审计监控 ORA- alert
--将所有数据库ora-错误写入表create table error_tab (username varchar2(4000), d_current_nr_error varchar2(4000), ora_server_error_msg varchar2(4000), full_text varchar2(4000),errdate date);create or replace trigger error_triggerafter servererror on database…...
React解决样式冲突问题的方法
React解决样式冲突问题的方法 前言: 1、React最终编译打包后都在一个html页面中,如果在两个组件中取一样类名分别引用在自身,那么后者会覆盖前者。 2、默认情况下,只要导入了组件,不管组件有没有显示在页面中&#x…...
Go项目(用户操作微服务)
简介 用户留言、收藏、修改收货地址等,统一放在用户操作微服务这里按照业务类型划分微服务表设计,三张表// 用户收藏 type UserFav struct {BaseModel// 联合索引 idx_user_goods,且唯一User int32 gorm:"type:int;index:idx_user_goo…...
Spring Boot统一功能处理
目录 一、统一用户登录权限验证 1.1 自定义拦截器 1.2 将自定义拦截器加入到系统配置 1.3 统一访问前缀 二、统一异常处理 三、统一数据格式返回 一、统一用户登录权限验证 1.1 自定义拦截器 拦截器是一个普通的类,需要实现HandlerInterceptor接口并重写pre…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
