当前位置:   article > 正文

DS18B20驱动详解(蓝桥杯单片机)_ds18b20搜索rom程序解析

ds18b20搜索rom程序解析

简介

DS18B20数字温度计提供9位到12位摄氏温度测量,并具有非易失性用户可编程上、下触发点报警功能。
DS18B20通过一根单线总线与中央微处理器通信,根据定义,该总线只需要一条数据线(和地)。它的工作温度范围为-55°C到+125°C,在范围- 10°C到+85°C上精确到±0.5°C。
此外,DS18B20可以直接从数据线获得电源(“寄生电源”),消除了外部电源的需求。

每个DS18B20都有一个独特的64位串行代码,它允许多个DS18B20在同一根单线总线上工作。因此,使用一个微处理器来控制分布在大范围内的多个DS18B20s是很简单的。受益于此功能的应用包括暖通空调环境控制,建筑内的温度监测系统,设备,或机械,过程监测和控制系统。

结构

在这里插入图片描述
图二

引脚描述表

引脚标号名字功能
3VDD可选,在寄生电源模式下VDD必须接地
2DQ数据输入/输出。当使用“寄生电源”模式时,也为设备提供电源(参见DS18B20电源部分)。
1GND地线

特性

  • 通信只需要一个端口引脚
  • 每个设备都有一个唯一的64位串行代码存储在板载ROM中
  • 分布式温度传感应用
  • 不需要外部组件可以从数据线供电
  • 供电范围3.0V ~ 5.5V
  • 测量温度从-55°C到+125℃(-67F到+257F)
  • 10°C到+85°C温度计为±0.5°C精度
  • 用户可选择分辨率从9到12位
  • 在750ms(最大时间)内将温度转换为12位数字字
  • 用户自定义NV (Nonvolatile)掉地可保存的告警设置
  • 告警搜索命令用于识别和寻址温度为的设备超出程序限制(温度警报条件)
  • ds1822应用包括恒温控制,工业系统、消费产品、温度计,或任何热敏物系统

原理

资源

通过图二(DS18B20框图)可以看出DS18B20所有的资源可以总结如下图

DS18B20 64位ROM部分 scratchpad存储部分 Temperature LSB Temperature MSB TH Register TL Register Configuration Register Reserved Reserved Reserved CRC* EEPROM TH Register TL Register Configuration Register

64位ROM

每个DS18B20包含一个唯一的64位代码(见下图)存储在ROM中。ROM代码的最低有效位8位包含DS18B20的家族代码:28h。接下来的48位包含一个唯一的序列号。高8位包含一个循环冗余校验(CRC)字节,它是从ROM代码的前56位计算出来的。64位ROM代码和相关的ROM功能控制逻辑允许ds18b20使用在1线总线系统上有多个器件同时工作。
在这里插入图片描述

scratchpad存储部分

在这里插入图片描述

存储部分包含了对DS18B20的所有配置读写等。

字节O和字节1分别包含温度寄存器的LSB和MSB。这些字节是只读的。
字节2和3提供对TH和T寄存器的访问。
第4字节包含配置寄存器数据
字节5、6、7保留给设备内部使用,不能被覆盖。
字节8的scratchpad是只读的,并且包含字节0到7的scratchpad的CRC代码DS18B20使用在CRC生成章节中描述的方法生成这个CRC。

Temperature LSB含义

测量温度的低八位
(数据如何处理还要看温度的分辨率,后面会解释)
在这里插入图片描述

Temperature MSB含义

测量温度的高八位
其中S是温度±标志,为正的时候S = 0, 为负的时候S = 1;
(数据如何处理还要看温度的分辨率,后面会解释)
在这里插入图片描述


TH Register or User Byte 1含义

包含温度上限+标志位

TL Register or User Byte 2含义

包含温度上限+标志位

概括

DS18B20进行温度转换后,转换后的温度值会与用户定义的温度上下限所比较,如下图,温度上下限格式都是如此。其中最高位为标志为,当超过限制的时候,标志为1,正常则为0。其余位为设定的温度值
在这里插入图片描述
由于TH和TL是8位寄存器,所以只有温度寄存器的第11位到第4位(温度高八位和低八位合起来)用于第TH和T的比较。如果测量的温度低于或等于TL或高于或等于TH,则存在告警条件并在DS18B20内部设置告警标志。该标志在每次温度测量后更新;因此,如果报警状态消失,则在下一次温度转换后,该标志将被关闭


Configuration Register含义

在这里插入图片描述
用户可以使用该寄存器中的R0和R1位设置DS18B20的转换分辨率,如下图所示。在上电的时候默认是R0 = 1和R1= 1(12位分辨率)。注意,在分辨率和转换时间之间有一个直接的权衡。配置寄存器中的第7位和第0位到第4位保留给设备内部使用,并且不能被覆盖。

在这里插入图片描述

CRC含义

在这里插入图片描述
对DS18B20的ROM以及scratchpad部分能够使用CRC校验。
ROM中CRC是将ROM代码的前56为送入上图的CRC生成器,然后在完成的时候将当前8个正方形框中的二进制代码加在56bit后面生成64为ROM码,以此来校验是否正确。
而scratchpad部分,是将scratchpad那前8个Byte送入(由Byte0的低位开始送入),完成后将当前8位写入scratchpad第九Byte。然后当用户读取温度的时候,就可以用单片机再次校验,查看温度转换是否正确。

EEPROM

在这里插入图片描述
可以看到EEPROM中包含的有TH以及TL还有configuration寄存器。这部分和scratchpad中的部分一一对应。也就是说使用相应的命令就可以实现将当前scratchpad中的相应值写入EEPROM中的相应部分。这部分看后续的操作命令即可


操作

这里就是重点
DS18B20操作原则:
DS18B20每次操作都分为三个步骤:

  1. 初始化
  2. ROM相关命令(后续包含任何数据交换的操作)
  3. 功能相关命令(后续包含任何数据交换的操作)

每次访问DS18B20时遵循这个顺序是非常重要的,因为DS18B20在序列中的任何步骤丢失或无序时都不会响应。这个规则的例外是命令Search ROM [FOh]和Alarm Search [ECh]命令。在发出这两个ROM命令中的任何一个之后,master必须返回到步骤1再次开始。
这个后续包含任何数据交换的操作含义就是,比如你发出了一个读ROM的命令,那么接下来DS18B20就会将ROM码发给你,类似这种。如果在操作完ROM后不需要操作功能相关命令,那么下次就直接从初始化开始即可。

初始化

所有事件都以初始化序列开始。初始化序列由主机发送的复位脉冲和由DS18B20从机发送的存在脉冲组成。存在脉冲让主机知道从属设备(如DS18B20)在总线上并且准备好操作。

ROM相关命令(后续包含任何数据交换的操作)

主机检测到DS18B20发出的存在脉冲后,它可以发出一个ROM命令。这些命令在每个从设备的唯一64位ROM代码上操作,并允许主设备单独挑选出一个特定的设备,如果许多设备存在于单线总线上。这些命令还允许主机确定总线上存在多少和什么类型的设备,或者是否有任何设备经历了警报状态。ROM命令共有5条,每条命令长度为8位。在发出DS18B20功能命令之前,主设备必须发出一个适当的ROM命令。ROM命令的操作流程图如图11所示。

SEARCH ROM [F0h]

当一个系统最初通电时,主机必须识别总线上所有从设备的ROM代码,这允许主机决定从设备的数量和它们的设备类型。这个过程要求主机执行一个搜索ROM循环(即,搜索ROM命令之后进行数据交换),尽可能多的次数来识别所有的从设备。如果在总线上只有一个从机,更简单的Read ROM命令可以用来代替搜索ROM进程。关于搜索ROM程序的详细说明,请参阅

READ ROM [33h]

此命令只能在总线上有一个从机时使用。它允许总线主机读从机的64位ROM代码而不使用搜索ROM过程。如果在总线上有多个从机时使用这个命令,那么当所有从服务器试图同时响应时,就会发生数据冲突。

MATCH ROM [55h]

匹配ROM命令后跟一个64位ROM代码序列允许总线主机在一个多点或单点总线上给一个特定的从设备寻址。只有与64位ROM代码序列完全匹配的从机才会响应主机发出的功能函数命令;总线上的所有其他从机将等待复位脉冲。

SKIP ROM [CCh]

主机可以使用这个命令来同时寻址总线上的所有设备,而不需要发送任何ROM代码信息。例如,主机可以通过发出Skip ROM命令,然后是Convert T [44h]命令,使总线上的所有DS18B20同时执行温度转换。注意,只有在总线上有一个从设备时,Read Scratchpad [BEh]命令才能跟随Skip ROM命令。在这种情况下,允许主机从从机读取而不发送设备的64位ROM代码可以节省时间。如果有多个从站,因为多个设备将尝试同时传输数据,一个跳过ROM命令后跟一个Read Scratchpad命令将导致总线上的数据碰撞。

ALARM SEARCH [ECh]

该命令的操作与Search ROM命令的操作相同,只是只有设置了报警标志的从机才会响应。这个命令允许主设备确定在最近的温度转换期间是否有任何DS18B20经历了告警状态。在每个警报搜索周期之后(即,警报搜索命令之后是数据交换),总线主机必须返回到事务序列中的第1步(初始化)。

功能相关命令(后续包含任何数据交换的操作)

总线主机使用ROM命令来寻址它希望与之通信的ds18b20后,主机可以发出DS18B20功能命令之一。这些命令允许主机对DS18B20的scratchpad存储器进行读写,启动温度转换并确定电源模式。

CONVERT T [44h]

该命令启动单个温度转换。转换之后,产生的热数据被存储在scratchpad内存中的2字节温度寄存器中,DS18B20返回到它的低功耗空闲状态。如果设备在寄生电源模式下使用,在这个命令发出后的10us (max)内,主机必须在转换(tcoNy)的持续时间内在为DS18B20供电部分中描述的1线总线上启用一个强上拉。==如果DS18B20由外部电源供电,主机可以在转换T命令后发出读时隙,DS18B20将响应通过发送一个0,温度转换正在进行,转换完成时一个1。==在寄生功率模式下,这种通知技术不能被使用,因为总线在转换期间被强上拉拉得很高。

WRITE SCRATCHPAD [4Eh]

这个命令允许主机将3字节的数据写入DS18B20的scratchpad。第一个数据字节被写入 TH ,第二个字节被写入TL ,第三个字节被写入配置寄存器(第4字节)。数据必须首先被传输最低有效位。在主机发出重置之前,所有三个字节都必须被写入,否则数据可能被损坏。

READ SCRATCHPAD [BEh]

这个命令允许主机读取scratchpad的内容。数据传输从字节0的最低有效位开始,直到第9个字节(字节8 CRC)被读取。如果只需要scratchpad数据的一部分,master可以在任何时候发出复位来终止读取。

COPY SCRATCHPAD [48h]

这个命令将scratchpad,TH、TL和配置寄存器(字节2、3和4)的内容复制到EEPROM。如果设备在寄生电源模式下使用,在这个命令发出后的10us (max)内,主机必须在单线总线上启用一个强上拉,至少10ms.

RECALL E2 [B8h]

该命令从EEPROM中召回告警触发器值(TH和T)和配置数据,并将数据分别以字节2、3和4的形式放置在scratchpad中。DS18B20将通过在召回进行时发送0,在召回完成时发送1来指示召回的状态。召回操作在设备上电时自动发生,因此只要设备上电,有效的数据就可以在scratchpad中获得。

READ POWER SUPPLY [B4h]

主设备发出这个命令,后面跟着一个读时隙来确定总线上是否有任何ds18b20s正在使用寄生电源。在读取时隙期间,寄生供电的DS18B20s将把总线拉低,外部供电的DS18B20s将让总线保持高电平。


协议

协议、功能命令以及驱动

注意
粗的黑线是主机的操作
细的黑线是上拉电阻的操作
粗的灰线是DS18B20的操作

单总线信号

DS18B20采用严格的单线通信协议来保证数据的完整性。该协议定义了几种信号类型:复位脉冲、存在脉冲、写0、写1、读0、读1。总线主机启动所有这些信号,除了存在脉冲。

初始化过程-复位和存在脉冲

所有与DS18B20的通信都以一个初始化序列开始,该序列由一个来自主机的复位脉冲和一个来自DS18B20的存在脉冲组成。
如下图所示。当DS18B20发送存在脉冲来响应复位时,它向主机指示它在总线上并且准备好操作。

  • 在初始化序列期间,总线主发送(Tx)复位脉冲通过拉低1线总线至少480us。
  • 总线主机然后释放总线并进入接收模式(Rx)。
  • 当总线被释放时,5K电阻拉高总线。当DS18B20检测到上升边缘时,等待15μus到60μs,然后DS18B20通过拉低总线60us到240us发送存在脉冲。
    在这里插入图片描述

写时隙

有两种写时隙:“写1”时隙和“写0”时隙。总线用一个写1时隙写一个逻辑1到DS18B20和一个写0时隙写一个逻辑0到DS18B20。所有写槽的持续时间必须小于60us,每个写槽之间必须有逻辑单元恢复的时间间隔。

  • 这两种写时隙都是由主机拉低单线总线来启动的(见下图)。
  • 为了产生一个写1时隙,在将1线总线拉低后,总线主必须在15us内释放1线总线。当母线被释放时,5k上拉电阻将母线拉高。
  • 为了产生写0时隙,在拉低总线后,总线主必须在时隙期间(至少60us)继续保持总线低电平。
  • DS18B20在一个窗口期间对单线总线进行采样,这个窗口在主机启动写时隙后持续15us到60us。如果总线在采样窗口期间是高电平,一个1被写入DS18B20,如果线路是低电平,一个0被写入DS18B20。
    在这里插入图片描述

读时隙

DS18B20只能在主机发出读时隙时向主机传输数据。因此,主机必须在发出read Scratchpad [BEh]或read Power Supply [B4h]命令后立即生成读时隙,以便DS18B20能够提供所请求的数据。

  • 一个读时隙是由主机拉低单线总线至少1us,然后释放总线(见下图)发起的。
  • 在主设备启动读时隙后,DS18B20将开始在总线上发送1或0。
  • DS18B20通过保持总线高电平来传输1,通过拉低总线来传输0。
  • 当发送0时,DS18B20将在时隙结束时释放总线,总线将被上拉电阻拉回它的高空闲状态。
  • 来自DS18B20的数据在下降沿发起读时隙后15us有效
  • 因此,主机必须释放总线,然后从开始的15us内采样总线状态
    在这里插入图片描述

DS18B20的使用

OK! 到这里DS18B20的全部信息就总结完毕了,从这里开始就开始介绍如何使用DS18B20了!上面的信息可以作为参考,根据使用情况再看!

蓝桥杯电子类DS18B20驱动

DS18B20使用的是单总线协议,此协议由于只有一根线用作通信,因此对通信的时序要求极高。因此对驱动协议的编写要特别注意。蓝桥杯单片机比赛在比赛的时候会提供驱动程序,就在赛点资源包里面的
在这里插入图片描述
在里面有onewire.c以及onewire.h就是单总线协议的驱动。在以往的比赛中,在里面的驱动都是针对51单片机所测试的,这和15单片机(STC15F2K60S2.h)还是有区别的。
51单片机是12T的单片机,而15单片机是1T的。
这个通俗意义上说就是,15单片机的速度是51单片机速度的12倍。因此在onewire上面的对时间的要求都要*12才能够满足15单片机

因此该驱动不是拿着就可以用的。需要修改一下
在这里插入图片描述

那么这个驱动给我们提供了哪些函数呢?

//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
//DS18B20设备初始化
bit init_ds18b20(void)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

就给我们提供了三个函数,初始化、写字节以及读字节。
那么我们需要结合上面说的规定来对它编写功能命令函数,来达到驱动芯片的目的。

首先,非常重要的是要按照操作顺序来,在上面的操作部分我写的有
在这里插入图片描述

uint ReadTemp()
{
	uint tempValue = 	0;
	//初始化,当返回0的时候说明初始化成功
	if(!init_ds18b20())
	{
		//ROM操作:因为是由一个器件在总线上面
		//因此可以跳过ROM命令
	 	Write_DS18B20(0xcc);
	 	//功能命令操作:温度转换
		Write_DS18B20(0x44);
		//等待温度转换完成,返回1的时候转换完成
		while(!DQ);
		//再次操作DS18B20的时候,又需要重新开始三步骤
		if(!init_ds18b20())
		{
			//跳过ROM命令
		 	Write_DS18B20(0xcc);
			//读取SCRATCHPAD 
			Write_DS18B20(0xbe);
			//读取第0字节温度低8位
			tempValue = Read_DS18B20();
			//读取第1字节温度高8位
			tempValue = ((uint)Read_DS18B20() << 8) | tempValue;
		}
	}
	return 	tempValue;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

在这里的tempValue的值是原始的12位温度值
在这里插入图片描述
因为平常的温度不可能为负值,因此11-15位的值都为0,整个16位数据就是温度的值,我们可以看到bit0的值是2-4 ,这个代表它的分辨率是2-4 = 0.0625,也就是说将读出来的这16bit数据*0.0625就是温度的值!
因此,你既可以在这个驱动函数中就将读出温度值装换为可以用的值,也可以在应用程序中再做处理。我这里用串口演示一下。

void main()
{
 	Init();
	UartInit();
	Timer1Init();
	while(1)
	{
	 Delay1000ms();
	 TI = 1;
	 printf("tempValue is %d\r\n", ReadTemp());
	 printf("tempValue*0.0625 is %f\r\n", ReadTemp()* 0.0625);						
	}

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

这里只帖了一部分代码,主要就是演示一下,不用过多参考

在这里插入图片描述

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/647938
推荐阅读
相关标签
  

闽ICP备14008679号