DS18B20初始化-读-写-温度转换
DS18B20
- (一)初始化
- (二)读字节
- (三)写字节
- (四)温度转换
- 1获得数据
- 2转换数据
(一)初始化
初始化时序:

- 数据线先拉到高电平,稍作延时即可(刚开始是高电平还是低电平芯片手册上其实不关心这一部分)
- 数据线拉到低电平
- 延时(480us~960us)
- 将数据线拉高电平
- 延时等待(大于60us)
- 判断有没有初始化成功;理论上电平在第4步置高后,DS18B20如果存在就会将数据线拉低
如果不存在就还是高电平 - 延时(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);
}
(二)读字节
时序图:

- 将数据线拉低
- 延时大于1us(不要太大,因为我延时后面还要执行一个语句,所以整体时间大于1us)
- 将数据线拉高
- 延时10us
- 处理数据
- 延时50us
- 重复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);
}
(三)写字节
时序图:

- 数据线拉低
- 延时15us
- 从低位到高位发送数据,一次一位
- 延时60us
- 拉高数据线
- 重复1~5
- 读完一个字节后要延时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(); //读出温度的低位LSBtempH=ReadOneChar(); //读出温度的高位MSB
}
2转换数据
-
格式

-
意义
tempH(xxxx x000):前5位是符号标志位(0-正数 1-负数); 后三位和低字节前4位的组成整数部分
tempL(0000 0000): 前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(如上图) -
代码(我用的是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);
}
- 效果图(有点简陋)

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
