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

本文详细介绍了DS18B20传感器的初始化步骤、字节读写操作以及温度转换流程,包括初始化时序、读写字节的时序图和温度值解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(一)初始化

初始化时序:
初始化

  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. 代码(我用的是QT(c++)编写的,大家用的编程语言不一样,但是算法一样)

//我用的是QT(c++)编写的,大家用的编程语言不一样,但是算法一样
QString DS18B20::CaculateTemp(quint8 tmh, quint8 tml)
{
    quint8 th;
    quint8 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;       //小数部分
    return QString::number(temp, '.', 2);
}
  1. 效果图(有点简陋)
    在这里插入图片描述
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m晴朗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值