DS18B20初始化-读-写-温度转换

目录

目录

前言

(一)初始化

(二)读字节

(三)写字节

(四)温度转换

1、获得数据

2、转换数据



前言

        DSI8B20接收到温度转换命令后,开始启动转换。转换完成后的温度值就以16位带符号扩展的二进制补码形式存储在高速暂存存储器的0,1字节。单片机可通过单线接口读到该数据,读取时低位在前,高位在后,数据格式以0.062 5℃/LSB形式表示。

        温度值格式如表2.2.1所示,其中“S”为标志位,对应的温度计算:当符号位S=0时,直接将二进制位转换为十进制,得到的温度值即为正温度值;当S=1时,测得的温度是零下温度值,DS18B20保存的是温度的补码值,需要对其低8位(LS Byte)取反加一变成原码。再计算十进制值,得到的温度值即为负温度值。

                      

        DS18B20的核心功能是直接温度-数字测量。其温度转换可由用户自定义为9、10、11、12位精度分别为0.5℃、0.25℃、0.125℃、0.0625℃分辨率。值得注意的是,上电默认为12位转换精度。

        DS18B20上电后工作在低功耗闲置状态下。主设备必须向DS18B20发送温度转换命令[44h]才能开始温度转换。温度转换后,温度转换的值将会保存在暂存存储器的温度寄存器中,并且DS18B20将会恢复到闲置状态。如果DS18B20是由外部供电,当发送完温度转换命令[44h]后,主设备可以执行“读数据时序”。若此时温度转换正在进行DS18B20将会响应“0”,若温度转换完成则会响应“1”。如果DS18B20是由“寄生电源”供电,该响应的技术将不能使用,因为在整个温度转换期间,总线必须强制拉高。

  DS18B20的温度输出数据时在摄氏度下校准的;若是在华氏度下应用的话,可以用查表法或者常规的数据换算。温度数据以一个16位标志扩展二进制补码数的形式存储在温度寄存器中(详见图2)。符号标志位(S )温度的正负极性:正数则S=0,负数则S=1。如果DS18B20被定义为12位的转换精度,温度寄存器中的所有位都将包含有效数据。若为11位转换精度,则bit 0为未。

        由于DS18B20转换后的代码并不是实际的温度值,所以要进行计算转换。温度高字节(MS Byte)高5位是用来保存温度的正负(标志为S的bit11~bit15),高字节(MS Byte)低3位和低字节来保存温度值(bit0 ~ bit10)。其中低字节(LS Byte)的低4位来保存温度的小数位(bit0 ~ bit 3)。由于本程序采用的是0.0625的精度,小数部分的值,可以用后四位代表的实际数值乘以0.0625,得到真正的数值,数值可能带几个小数位,所以采取小数舍入,保留一位小数即可。也就说,本系统的温度精确到了0.1度。 
 

  

(一)初始化

初始化时序:

初始化

  1.  数据线先拉到高电平,稍作延时即可(刚开始是高电平还是低电平芯片手册上其实不关心这一部分)
  2. 数据线拉到低电平
  3. 延时(480us~960us)
  4. 将数据线拉高电平
  5. 延时等待(大于60us)
  6. 判断有没有初始化成功;理论上电平在第4步置高后,DS18B20如果存在就会将数据线拉低如果不存在就还是高电平
  7. 延时(cpu读到18b20回应的低电平后,还要做延时;其时间是从发出高电平(第4步)时间算起,至少要480us
/********************FunctionDescription_Start********************************
* @Name   : Init_DS18B20
* @param  :None
* @author : m晴朗
* @Data   : 2021-11-26
* @return :       
* @PURPOSE: 初始化DS18B20
1.数据线先拉到高电平,稍作延时即可(刚开始是高电平还是低电平芯片手册上其实不关心这一部分)
2.数据线拉到低电平
3.延时(480us~960us)
4.将数据线拉高电平
5.延时等待(DS18B20回应时间是15~60us,在我自己的硬件上测试出来是27us恢复,
  所有我这里设置延时40us,如果不知道是多长时间回应,可以设置大于60us
6.判断有没有初始化成功;理论上电平在第4步置高后,DS18B20如果存在就会将数据线拉低
  如果不存在就还是高电平
7.延时(cpu读到18b20回应的低电平后,还要做延时;其时间是从发出高电平(第4步)时间算起,至少要480us
/********************FunctionDescription_End*********************************/
void Init_DS18B20(void)
{
    DQ=1; 					     
    delay1us(2); 		     
    DQ=0; 					     
    delay1us(500);       
    DQ=1; 					     
    delay1us(40); 		  
    isTemp=DQ; 		       
    delay1us(440);
}

(二)读字节

时序图:

读字节

  1. 将数据线拉低
  2. 延时大于1us(不要太大,因为我延时后面还要执行一个语句,所以整体时间大于1us)
  3. 将数据线拉高
  4. 延时10us
  5. 处理数据
  6. 延时50us
  7. 重复1~6,直至读完一个字节
/********************FunctionDescription_Start********************************
* @Name   : ReadOneChar
* @param  :None
* @author : m晴朗
* @Data   : 2021-11-26
* @return :       
* @PURPOSE: 读一个字节
1.将数据线拉低
2.延时大于1us(不要太大,因为我延时后面还要执行一个语句,所以整体时间大于1us)
3.将数据线拉高
4.延时10us
5.处理数据
6.延时50us
7.重复1~6,直至读完
/********************FunctionDescription_End*********************************/
Byte ReadOneChar(void)  			
{
    Byte i=0; 		
    Byte dat=0;
    for (i=8; i>0; i--) 		//一个字节有8位
    {
        DQ=0;
        delay1us(1);
        dat>>=1;
        DQ=1;
        delay1us(10);
        if(DQ)
            dat|=0x80;
        delay1us(50);
    }
    return(dat);
}

(三)写字节

时序图:

写字节

  1. 数据线拉低
  2. 延时15us
  3. 从低位到高位发送数据,一次一位
  4. 延时60us
  5. 拉高数据线
  6. 重复1~5
  7. 读完一个字节后要延时40us
/********************FunctionDescription_Start********************************
* @Name   : WriteOneChar
* @param  :dat: [输入/出] 
* @author : m晴朗
* @Data   : 2021-11-26
* @return :       
* @PURPOSE: 写一个字节
1.数据线拉低
2.延时15us
3.从低位到高位发送数据,一次一位
4.延时60us
5.拉高数据线
6.重复1~5
7.读完一个字节后要延时40us
/********************FunctionDescription_End*********************************/
void WriteOneChar(Byte dat)
{
    unsigned char i=0; 	
    for(i=8; i>0; i--) 		 
    {
        DQ=0; 				      
        delay1us(15);
        DQ=dat&0x01;
        delay1us(68);
        DQ=1;
        dat>>=1;
    }
    delay1us(40);
}

(四)温度转换

1、获得数据

/********************FunctionDescription_Start********************************
* @Name   : ReadTemperature
* @param  :None
* @author : m晴朗
* @Data   : 2021-11-26
* @return :       
* @PURPOSE: 读温度值(低位放tempL;高位放tempH;)
/********************FunctionDescription_End*********************************/
void ReadTemperature(void)
{
    Init_DS18B20(); 					  //初始化
    WriteOneChar(0xcc); 				  //跳过读序列号的操作
    WriteOneChar(0x44); 				  //启动温度转换
    delay1us(800); 						  //转换需要一点时间,延时
    Init_DS18B20(); 				  	  //初始化
    WriteOneChar(0xcc); 				  //跳过读序列号的操作
    WriteOneChar(0xbe); 				  //读温度寄存器(头两个值分别为温度的低位和高位)
    tempL=ReadOneChar(); 				  //读出温度的低位LSB
    tempH=ReadOneChar(); 				  //读出温度的高位MSB
}

2、转换数据

(1)、格式

格式

(2)、意义
tempH(xxxx x000):前5位是符号标志位(0-正数 1-负数);后三位和低字节前4位的组成整数部分
tempL(0000 0000):前4位和高字节的后三位组成整数部分; 后四位为小数部分

(3)、温度表示图

图

 (4)、实例计算

(1) 正数:

16进制是:00A2H
2进制是:0000 0000 1010 0010
取高字节后3位和低字节前4位:000 1010
转成10进制:10
低字节后4位:02-1+02-2+12-3+02-4=0.125(02-1为02的-1次方)
结果:10+0.125=10.125(如上图)

(2)负数:

16进制是:FF5EH
2进制是:1111 1111 0101 1110
取高字节后3位和低字节前4位:111 0101
取反加1:000 1011
转成10进制:11
加负号:-11
低字节后4位:12-1+12-2+12-3+02-4=0.875(02-1为02的-1次方)
结果:-11+0.875=-10.125(如上图)


 (5)、代码


int16_t CaculateTemp(uint8_t tmh, uint8_t tml)
{
    uint8_t th;
    uint8_t tl;
    double temp = 0;


    tl = tml & 0x0F;               //取低字节后四位
    th = (tmh << 4) + (tml >> 4);  //取高字节后三位和低字节前四位
    temp = (int)th;                //整数部分
    if (tmh > 0x08)
    {
        th = ~th + 1;            	//取反加一
        temp = -th;              	//负数
    }
    temp += tl * 0.0625;       		//小数部分
	temp = temp * 10;				//放大10倍(上位机显示时带1位小数点)
    return (temp);
}

致谢: (10条消息) DS18B20初始化-读-写-温度转换_m晴朗的博客-CSDN博客_ds18b20初始化

致谢:(12条消息) DS18B20温度换算_把钱打进来的博客-CSDN博客_ds18b20温度转换公式 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值