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

DS18B20

  • (一)初始化
  • (二)读字节
  • (三)写字节
  • (四)温度转换
    • 1获得数据
    • 2转换数据

(一)初始化

初始化时序:
DS18B20初始化-读-写-温度转换_第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);
}

(二)读字节

时序图:
DS18B20初始化-读-写-温度转换_第2张图片

  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);
}

(三)写字节

时序图:
DS18B20初始化-读-写-温度转换_第3张图片

  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. 格式
    DS18B20初始化-读-写-温度转换_第4张图片

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

  3. 温度表示图
    DS18B20初始化-读-写-温度转换_第5张图片

  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. 效果图(有点简陋)
    DS18B20初始化-读-写-温度转换_第6张图片

你可能感兴趣的:(硬件,单片机,c语言,arm,嵌入式硬件)