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…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...

苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...

【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
LRU 缓存机制详解与实现(Java版) + 力扣解决
📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...