ds18b20为什么要初始化(DS18B20初始化-读-写-温度转换)

(一)初始化

初始化时序:

ds18b20为什么要初始化(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: 初始化DS18B201.数据线先拉到高电平,稍作延时即可(刚开始是高电平还是低电平芯片手册上其实不关心这一部分)2.数据线拉到低电平3.延时(480us~960us)4.将数据线拉高电平5.延时等待(DS18B20回应时间是15~60us,在我自己的硬件上测试出来是27us恢复,所有我这里设置延时40us,如果不知道是多长时间回应,可以设置大于60us6.判断有没有初始化成功;理论上电平在第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为什么要初始化(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.延时10us5.处理数据6.延时50us7.重复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为什么要初始化(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.延时15us3.从低位到高位发送数据,一次一位4.延时60us5.拉高数据线6.重复1~57.读完一个字节后要延时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转换数据
  1. 格式
  2. 意义tempH(xxxx x000):前5位是符号标志位(0-正数 1-负数); 后三位和低字节前4位的组成整数部分tempL(0000 0000): 前4位和高字节的后三位组成整数部分; 后四位为小数部分
  3. 温度表示图
  4. 实例计算(1) 正数:16进制是:00A2H2进制是: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进制是:FF5EH2进制是: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. 效果图(有点简陋)
,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页