8、单总线与DB18B20实现温度的测量

2023-10-25 07:00

本文主要是介绍8、单总线与DB18B20实现温度的测量,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 1、单总线(1-Wire)通信的基本概念
    • 2、DS18B20温度传感器的介绍
          • 1)ROM操作指令
          • 2)功能性指令
    • 3、DS18B20 的数据格式及转换
    • 4、 DS18B20 的时序图
          • 1)主机的两个写入操作
          • 2)从机的两个应答操作(主机读0读1)
    • 5、 DS18B20 的操作流程
    • 6、参考代码

1、单总线(1-Wire)通信的基本概念

在串行通信系统中通常具备:
时钟信号线,数据信号线,控制信号线,设备电源线

  • UART:VCC GND TXD(串口的发送引脚) RXD(串口的接收引脚)
  • USART:VCC GND TXD RXD SCK(时钟信号)
  • SPI:VCC GND CS(片选引脚) MOSI MISO SCK
  • I2C:VCC GND SDA(串行数据线) SCK(串行时钟线)

优缺点:

  1. 总线的驱动能力较差,超过一定数量会不稳定
  2. 距离不长,1-Wire总线更适合中短距离低速
  3. 由于硬件集成一线比较简单,软件的复杂度上升

2、DS18B20温度传感器的介绍

  • 1、外形
    在这里插入图片描述
  • 2、供电方式
    寄生方式供电
    在这里插入图片描述
    在这里插入图片描述
    外部供电方式(需要考虑压降)
    在这里插入图片描述
  • 3、内部电路
    内部含有单元电源单元,ROM单元,存储器逻辑控制单元,温度转换单元,高速暂存器单元等
    在这里插入图片描述
    DS18B20只能去读而不能写,具备高温报警,-10°-40°
1)ROM操作指令

DS18B20设备中有关ROM操作的指令一共有5个,如下所示:

在这里插入图片描述
(读取和跳过用得比较多,其他的用得比较少)

2)功能性指令

除了ROM指令在之外,还有功能性的指令
在这里插入图片描述
(主要用的是温度转换和读暂存器)

3、DS18B20 的数据格式及转换

  1. 转换分配率问题
    在配置寄存器中的位 6 和位 5 两个位来控制
    在这里插入图片描述
  2. 温度值的存放问题
    在高字节中的高 5 位是符号位,图中用 S 表示。如果温度值是正数,则 S 位均为 0,若为负数,则 S 位均为 1
    在这里插入图片描述
  • 问题1:符号位为什么要5个?

没有必要占用这么多位,其可测量的温度范围比较窄,为了数据好处理,所以用了5个符号位。

  • 问题2:抛开符号位,其他的全部为只有11位?

将高位的5为结合成了一个符号位,也就是12位的分辨率指的是S位+其余的11位。
位0-位3部分是小数部分,位4-位19是整数部分,位11-位15是符号位。对于12位的转换分辨率,温度传感器的所以位都是有效的;对于11为的转换分辨率,位0是无效的;对于10为的分辨率,位0和位1是无效的;对于9位的分辨率,位2,位1,位0是无效的。

  • 问题3:负数温度如何处理?

负数温度按照补码来操作,所以如果是-55°需要存储,其正确的答案不是0b1111101101110000也就是0xFB70,而是按照补码来显示为0b1111110010010000也就是0xFC90。(补码=反码+1,反码=源码取反)

  • 问题4:温度如何转换为正确的摄氏温度?

实际温度 = 份数 * 最小的分辨率

温度数值转换格式的例子:
在这里插入图片描述
高温阈值和低温阈值的设置(少用)
在这里插入图片描述
当实际采样测量的温度值超过高温限值或者是低于低温阈值的时候,这时候DS18B20设备会发出报警信号。

4、 DS18B20 的时序图

DS18B20 设备采用了严格的 1-Wire 单总线通信协议来保证数据的完整性和有效性。第一是发送初始化时序,第二是发送 ROM 命令,第三是发送功能命令。
在这里插入图片描述

  • 问题:如何写命令给从机,也就是如何让从机知道我们是写 1 还是写 0,才能将一个 1byte的数据发送过去?

对于一个字节的数据,有高低位之分,而数据的发送要先发低位,再发高位。注意好写 0 和写 1 的时间隙。在正确的时间隙中操作就是主机与从机之间正确通信的保障。

1)主机的两个写入操作
  • 操作1:写1的时间隙
    在这里插入图片描述
  • 操作2:写0的时间隙
    在这里插入图片描述
2)从机的两个应答操作(主机读0读1)

在这里插入图片描述
注意要注意好时间,主机的采样一定要是15微秒以内

在这里插入图片描述
在这里插入图片描述

5、 DS18B20 的操作流程

  1. 复位
    首先我们必须对 ds18b20 芯片进行复位,复位就是由控制器(单片机)给 ds18b20 单
    总线至少 480uS 的低电平信号。当 18B20 接到此复位信号后则会在 15~60uS 后回发一个芯
    片的存在脉冲。
  2. 存在脉冲
    在复位电平结束之后,控制器应该将数据单总线拉高,以便于在 15~60uS 后接收存在
    脉冲,存在脉冲为一个 60~240uS 的低电平信号。至此,通信双方已经达成了基本的协议,
    接下来将会是控制器与 18B20 间的数据通信。如果复位低电平的时间不足或是单总线的电
    路断路都不会接到存在脉冲,在设计时要注意意外情况的处理。
  3. 控制器发送 ROM 指令
    双方打完了招呼之后最要将进行交流了,ROM 指令共有 5 条,每一个工作周期只能发一
    条,ROM 指令分别是读 ROM 数据、指定匹配芯片、跳跃 ROM、芯片搜索、报警芯片搜索。ROM
    指令为 8 位长度,功能是对片内的 64 位光刻 ROM 进行操作。其主要目的是为了分辨一条总
    线上挂接的多个器件并作处理。诚然,单总线上可以同时挂接多个器件,并通过每个器件
    上所独有的 ID 号来区别,一般只挂接单个 18B20 芯片时可以跳过 ROM 指令(注意:此处指
    的跳过 ROM 指令并非不发送 ROM 指令,而是用特有的一条“跳过指令”)。ROM 指令在下
    文有详细的介绍。
  4. 控制器发送存储器操作指令
    在 ROM 指令发送给 18B20 之后,紧接着(不间断)就是发送存储器操作指令了。操作
    指令同样为 8 位,共 6 条,存储器操作指令分别是写 RAM 数据、读 RAM 数据、将 RAM 数据
    复制到 EEPROM、温度转换、将 EEPROM 中的报警值复制到 RAM、工作方式切换。存储器操作
    指令的功能是命令 18B20 作什么样的工作,是芯片控制的关键。
  5. 执行或数据读写
    一个存储器操作指令结束后则将进行指令执行或数据的读写,这个操作要视存储器操
    作指令而定。如执行温度转换指令则控制器(单片机)必须等待 18B20 执行其指令,一般
    转换时间为 500uS。如执行数据读写指令则需要严格遵循 18B20 的读写时序来操作。
    需要注意:
    换存储器操作指令、等待 500uS 温度转换时间。紧接着执行第二个周期为复位、跳过
    ROM 指令、执行读 RAM 的存储器操作指令、读数据(最多为 9 个字节,中途可停止,只读
    简单温度值则读前 2 个字节即可)。其它的操作流程也大同小异,在此不多介绍。

6、参考代码

/****************************************************************/
//设备初始化时序产生函数DS18B20_reset(),无形参和返回值
/****************************************************************/
void DS18B20_reset(void)
{u8 x;DS18B20_DQ_DDR(1);DS18B20_DQ=1;delay(1700);DS18B20_DQ=0;delay(1700);DS18B20_DQ=1;delay(65);DS18B20_DQ_DDR(0);delay(65);x=PI_IDR_IDR4;printf("|[1].开始检测DS18B20......\r\n");while(x);printf("|[2].DS18B20检测成功\r\n");delay(1150);//控制器等待至少480us
}/****************************************************************/
//设备DQ引脚方向性配置函数DS18B20_DQ_DDR(),有形参ddr无返回值
/****************************************************************/
void DS18B20_DQ_DDR(u8 ddr)
{if(ddr==1)	//配置为输出方式{PI_DDR_DDR4=1;PI_CR1_C14=1;PI_CR2_C24=0;}else			//配置为输入方式{PI_DDR_DDR4=0;PI_CR1_C14=1;PI_CR2_C24=0;}
}/****************************************************************/
//设备初始化函数DS18B20_init(),无形参和返回值
/****************************************************************/
void DS18B20_init(void)
{DS18B20_reset();delay(1000);DS18B20_Wbyte(0xCC);//写ROM指令(跳过ROM)DS18B20_Wbyte(0x44);//写功能指令(温度转换)printf("|[3].启用温度转换\r\n");
}/****************************************************************/
//设备写一个字节函数DS18B20_Wbyte(),有形参xbyte无返回值
/****************************************************************/
void DS18B20_Wbyte(u8 xbyte)
{u8 i,x=0;DS18B20_DQ_DDR(1);for(i=0;i<8;i++)	//8次循环实现逐位写入{x=xbyte & 0x01; //从最低位取值到最高位if(x)			//写“1”{DS18B20_DQ=0;delay(30);DS18B20_DQ=1;delay(100);DS18B20_DQ=1;}else			//写“0”{DS18B20_DQ=0;delay(30);DS18B20_DQ=0;delay(100);DS18B20_DQ=1;}xbyte=xbyte>>1;	//右移一位实现逐位移出}
}/****************************************************************/
//设备读字节函数DS18B20_Rbyte(),无形参有返回值rbyte
/****************************************************************/
u8 DS18B20_Rbyte(void)
{u8 rbyte=0,i=0,tempbit=0;for(i=0;i<8;i++)	//8次循环实现逐位拼合{tempbit=DS18B20_Rbit();	//读取单个位rbyte=rbyte>>1;			//右移实现将高低位排列rbyte=rbyte|tempbit;	//或运算移入数据}return rbyte;
}/****************************************************************/
//设备读取单个位函数DS18B20_Rbit(),无形参有返回值rbit
/****************************************************************/
u8 DS18B20_Rbit(void)
{u8 rbit=0,x=0;DS18B20_DQ_DDR(1);DS18B20_DQ=0;delay(30);DS18B20_DQ=1;DS18B20_DQ_DDR(0);delay(20);x=PI_IDR_IDR4;if(x)rbit=0x80;delay(150);return rbit;
}/****************************************************************/
//设备温度获取和转换函数DS18B20_get_Temperature(),无形参和返回值
/****************************************************************/
void DS18B20_get_Temperature(void)
{u8 msb_byte=0,lsb_byte=0;	//msb是温度值高位,lsb是温度值低位DS18B20_reset();			//初始化时序delay(1000);				//等待初始化稳定DS18B20_Wbyte(0xCC);		//写ROM指令(跳过ROM)DS18B20_Wbyte(0xBE);		//写功能指令(读暂存器)delay(1000);				//等待配置稳定printf("|[4].开始温度读取操作\r\n");lsb_byte=DS18B20_Rbyte();	//读取第一个低位数据字节msb_byte=DS18B20_Rbyte();	//读取第二个高位数据字节Tem_u16=msb_byte;			Tem_u16=Tem_u16<<8;		Tem_u16=Tem_u16|lsb_byte;	if(Tem_u16<=0x07FF)		//温度值正负判断{flag=1;					//温度值为正(最高能测到125摄氏度)Tem_f=Tem_u16*0.0625;	//乘以0.0625最小分辨值得到12位温度实际值Tem_u16=(u16)(Tem_f+0.5);//4舍5入得到温度整数值}else{flag=0;					//温度值为负(最低能测到-55摄氏度)Tem_u16=~(Tem_u16-1);	//此时数据是补码形式//采用“补码-1”再按位取反的方法得到对应原码Tem_f=Tem_u16*0.0625;//乘以0.0625最小分辨值得到12位温度实际值Tem_u16=(u16)(Tem_f+0.5);//4舍5入得到温度整数值}
}

曾经做过一个单片机课设,实现DB18B20获取温度然后使用LCD1602显示,并且串口打印出来,有兴趣的可以下载代码

这篇关于8、单总线与DB18B20实现温度的测量的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/280838

相关文章

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

Python实现字典转字符串的五种方法

《Python实现字典转字符串的五种方法》本文介绍了在Python中如何将字典数据结构转换为字符串格式的多种方法,首先可以通过内置的str()函数进行简单转换;其次利用ison.dumps()函数能够... 目录1、使用json模块的dumps方法:2、使用str方法:3、使用循环和字符串拼接:4、使用字符

Linux下利用select实现串口数据读取过程

《Linux下利用select实现串口数据读取过程》文章介绍Linux中使用select、poll或epoll实现串口数据读取,通过I/O多路复用机制在数据到达时触发读取,避免持续轮询,示例代码展示设... 目录示例代码(使用select实现)代码解释总结在 linux 系统里,我们可以借助 select、

Linux挂载linux/Windows共享目录实现方式

《Linux挂载linux/Windows共享目录实现方式》:本文主要介绍Linux挂载linux/Windows共享目录实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录文件共享协议linux环境作为服务端(NFS)在服务器端安装 NFS创建要共享的目录修改 NFS 配

通过React实现页面的无限滚动效果

《通过React实现页面的无限滚动效果》今天我们来聊聊无限滚动这个现代Web开发中不可或缺的技术,无论你是刷微博、逛知乎还是看脚本,无限滚动都已经渗透到我们日常的浏览体验中,那么,如何优雅地实现它呢?... 目录1. 早期的解决方案2. 交叉观察者:IntersectionObserver2.1 Inter

Spring Gateway动态路由实现方案

《SpringGateway动态路由实现方案》本文主要介绍了SpringGateway动态路由实现方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随... 目录前沿何为路由RouteDefinitionRouteLocator工作流程动态路由实现尾巴前沿S