请点上面蓝色字 ,欢迎关注!
一.概述
DS18B20采用的1-Wire通信即仅采用一个数据线(以及地)与微控制器进行通信,采集数据的精度为12bit。该传感器的温度检测范围为-55℃至+125℃,并且在温度范围超过-10℃至85℃之外时还具有+-0.5℃的精度。此外,DS18B20可以直接由数据线供电而不需要外部电源供电。
二.电气参数
1.特点
- 供电电压:3.0V-5.5V。
- 测量温度范围:-55~+125℃
- 精度:±0.5℃
- 数据传输:“一线总线”的数字方式传输
- 采集精度:可以由用户自定义为9-Bits至12-Bits。
2.引脚说明
3.参考电路图
DS18B20供电一般采用外部供电方式,并且在数据线上并联一个4.7k的上拉电阻,以增强数据的抗干扰能力。
三.控制时序
1.初始化时序
与DS18B20所有的通信都是由初始化时序开始的,该时序包括从主设备发出的复位脉冲及从DS18B20响应的存在脉冲组成。如图所示。
当DS18B20响应复位信号的存在脉冲后,则其向主设备表明其在该总线上,并且已经做好操作命令。
/******************************************************************************** 函 数 名 : Ds18b20Init* 函数功能 : 初始化* 输 入 : 无* 输 出 : 初始化成功返回1,失败返回0*******************************************************************************/uchar Ds18b20Init(){ unsigned char x=0; DSPORT = 1; //DQ复位 Delay_DS18B20(8); //稍做延时 DSPORT = 0; //单片机将DQ拉低 Delay_DS18B20(80); //精确延时,大于480us DSPORT = 1; //拉高总线 Delay_DS18B20(14); x = DSPORT; //稍做return x;//初始化成功}
2.读时序
写时段有两种情况:“写1”时段和“写0”时段。主设备通过写1时段来向DS18B20中写入逻辑1以及通过写0时段来向DS18B20中写入逻辑0。每个写时段最小必须有60us的持续时间且独立的写时段间至少有1us的恢复时间。两个写时段都是由主设备通过将1-Wire总线拉低来进行初始化,如图。
根据以上读0及1的时序,便可实现读取一个完整字节的函数,如下:
/******************************************************************************** 函 数 名 : Ds18b20ReadByte* 函数功能 : 读取一个字节* 输 入 : 无* 输 出 : dat*******************************************************************************/uchar Ds18b20ReadByte(){ unsigned char i=0; unsigned char dat = 0; for (i=8;i>0;i--) { DSPORT = 0; // 给脉冲信号 dat>>=1; DSPORT = 1; // 给脉冲信号 if(DSPORT) dat|=0x80; Delay_DS18B20(4); } return(dat);}
3.写时序
仅在读时段期间DS18B20才能向主设备传送数据。因此,主设备在执行完读暂存寄存器[BEh]或读取供电模式[B4h]后,必须及时地生成读时段,这样DS18B20才能提供所需的数据。此外,主设备可以在执行完转换温度[指令:44h]或拷贝EEPROM[指令:B8h]命令后生成读时段,以便获得在“DS18B20功能命令”表中提到的操作信息。时序如图:根据以上写0及1的时序,便可实现写入一个完整字节的函数,如下:
/******************************************************************************** 函 数 名 : Ds18b20WriteByte* 函数功能 : 向18B20写入一个字节* 输 入 : com* 输 出 : 无*******************************************************************************/void Ds18b20WriteByte(uchar dat){ unsigned char i=0; for (i=8; i>0; i--) { DSPORT = 0; DSPORT = dat&0x01; Delay_DS18B20(5); DSPORT = 1; dat>>=1; }}
四.控制程序
1.读取温度流程
要读取一个完整的温度值,需要根据以上流程进行操作。先对DS18B20进行复位操作,再发送开始转换指令(指令值:0x44),再发送复位操作,等待DS18B20应答后,发送读取温度指令,最后就可以读取16位的数据(有限位最大为12位)。
2.读取温度程序
/******************************************************************************** 函 数 名 : Ds18b20ChangTemp* 函数功能 : 让18b20开始转换温度* 输 入 : 无* 输 出 : 无*******************************************************************************/void Ds18b20ChangTemp(){ Ds18b20Init(); Delay1ms(1); Ds18b20WriteByte(0xcc); //跳过ROM操作命令 Ds18b20WriteByte(0x44); //温度转换命令// Delay1ms(100); //等待转换成功,而如果你是一直刷着的话,就不用这个延时了}/******************************************************************************** 函 数 名 : Ds18b20ReadTempCom* 函数功能 : 发送读取温度命令* 输 入 : 无* 输 出 : 无*******************************************************************************/void Ds18b20ReadTempCom(){ Ds18b20Init(); Delay1ms(1); Ds18b20WriteByte(0xcc); //跳过ROM操作命令 Ds18b20WriteByte(0xbe); //发送读取温度命令}/******************************************************************************** 函 数 名 : Ds18b20ReadTemp* 函数功能 : 读取温度* 输 入 : 无* 输 出 : 温度值*******************************************************************************/int Ds18b20ReadTemp(){ int temp = 0; uchar tmh, tml; Ds18b20ChangTemp(); //先写入转换命令 Ds18b20ReadTempCom(); //然后等待转换完后发送读取温度命令 tml = Ds18b20ReadByte(); //读取温度值共16位,先读低字节 tmh = Ds18b20ReadByte(); //再读高字节 temp = tmh; temp <<= 8; temp |= tml; return temp;}/******************************************************************************** 函 数 名 : GetTemp* 函数功能 : 串口输出温度值* 输 入 : 无* 输 出 : 无*******************************************************************************/Void GetTemp(void){ int temp; float tp; ET0 = 0; temp = Ds18b20ReadTemp(); ET0 = 1; if(temp<= 0) //当温度值为负数 {// temp=temp-1;// temp=~temp;// tp=temp;// temp=tp*0.0625*100+0.5; Uart_SendString("Overrate!\r\n"); //超过量程 } else { tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量 //如果温度是正的那么,那么正数的原码就是补码它本身 temp=tp*0.0625*100+0.5; //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点 //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就 //算加上0.5,还是在小数点后面。 } Uart_SendString("The Current Temperature is: "); Uart_SendByte((temp% 10000 / 1000) + 0x30); Uart_SendByte((temp% 1000 / 100) + 0x30); Uart_SendByte('.'); Uart_SendByte((temp% 100 / 10) + 0x30); Uart_SendByte((temp% 10) + 0x30); Uart_SendString("℃\r\n"); }
如需
DS18B20相关资料及例程, 请关注公众号,首页回复
DS18B20获取资料