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

相关文章

HTML5 getUserMedia API网页录音实现指南示例小结

《HTML5getUserMediaAPI网页录音实现指南示例小结》本教程将指导你如何利用这一API,结合WebAudioAPI,实现网页录音功能,从获取音频流到处理和保存录音,整个过程将逐步... 目录1. html5 getUserMedia API简介1.1 API概念与历史1.2 功能与优势1.3

Java实现删除文件中的指定内容

《Java实现删除文件中的指定内容》在日常开发中,经常需要对文本文件进行批量处理,其中,删除文件中指定内容是最常见的需求之一,下面我们就来看看如何使用java实现删除文件中的指定内容吧... 目录1. 项目背景详细介绍2. 项目需求详细介绍2.1 功能需求2.2 非功能需求3. 相关技术详细介绍3.1 Ja

使用Python和OpenCV库实现实时颜色识别系统

《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解

PostgreSQL中MVCC 机制的实现

《PostgreSQL中MVCC机制的实现》本文主要介绍了PostgreSQL中MVCC机制的实现,通过多版本数据存储、快照隔离和事务ID管理实现高并发读写,具有一定的参考价值,感兴趣的可以了解一下... 目录一 MVCC 基本原理python1.1 MVCC 核心概念1.2 与传统锁机制对比二 Postg

SpringBoot整合Flowable实现工作流的详细流程

《SpringBoot整合Flowable实现工作流的详细流程》Flowable是一个使用Java编写的轻量级业务流程引擎,Flowable流程引擎可用于部署BPMN2.0流程定义,创建这些流程定义的... 目录1、流程引擎介绍2、创建项目3、画流程图4、开发接口4.1 Java 类梳理4.2 查看流程图4

C++中零拷贝的多种实现方式

《C++中零拷贝的多种实现方式》本文主要介绍了C++中零拷贝的实现示例,旨在在减少数据在内存中的不必要复制,从而提高程序性能、降低内存使用并减少CPU消耗,零拷贝技术通过多种方式实现,下面就来了解一下... 目录一、C++中零拷贝技术的核心概念二、std::string_view 简介三、std::stri

C++高效内存池实现减少动态分配开销的解决方案

《C++高效内存池实现减少动态分配开销的解决方案》C++动态内存分配存在系统调用开销、碎片化和锁竞争等性能问题,内存池通过预分配、分块管理和缓存复用解决这些问题,下面就来了解一下... 目录一、C++内存分配的性能挑战二、内存池技术的核心原理三、主流内存池实现:TCMalloc与Jemalloc1. TCM

OpenCV实现实时颜色检测的示例

《OpenCV实现实时颜色检测的示例》本文主要介绍了OpenCV实现实时颜色检测的示例,通过HSV色彩空间转换和色调范围判断实现红黄绿蓝颜色检测,包含视频捕捉、区域标记、颜色分析等功能,具有一定的参考... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间

Python实现精准提取 PDF中的文本,表格与图片

《Python实现精准提取PDF中的文本,表格与图片》在实际的系统开发中,处理PDF文件不仅限于读取整页文本,还有提取文档中的表格数据,图片或特定区域的内容,下面我们来看看如何使用Python实... 目录安装 python 库提取 PDF 文本内容:获取整页文本与指定区域内容获取页面上的所有文本内容获取

基于Python实现一个Windows Tree命令工具

《基于Python实现一个WindowsTree命令工具》今天想要在Windows平台的CMD命令终端窗口中使用像Linux下的tree命令,打印一下目录结构层级树,然而还真有tree命令,但是发现... 目录引言实现代码使用说明可用选项示例用法功能特点添加到环境变量方法一:创建批处理文件并添加到PATH1