DS18B20的调试总结和程序

传感器

273人已加入

描述

DS18B20简介

DS18B20是常用的数字温度传感器,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。 DS18B20数字温度传感器接线方便,封装成后可应用于多种场合,如管道式,螺纹式,磁铁吸附式,不锈钢封装式,型号多种多样,有LTM8877,LTM8874等等。

主要根据应用场合的不同而改变其外观。封装后的DS18B20可用于电缆沟测温,高炉水循环测温,锅炉测温,机房测温,农业大棚测温,洁净室测温,弹药库测温等各种非极限温度场合。耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温和控制领域。

单个18B20实现温度测试步骤

该文档所用程序为FREESCALE JM60单片机,总线时钟为8M,若要移植到其它MCU上,需要将时间重新调节,或者更改总线时钟频率的输出;

DS18B20

电路图

DS18B20

DS18B20工作协议:初始化,存储器操作命令,处理数据;

DS18B20

在关于时序的编写中,for循环中的NOP指令,和单独调用的NOP指令所用时间完全不同;NOP占用1/总线时

钟的时间;如JM60的总线时钟为8M,则NOP指令一定占用0.125US,而将NOP放在FOR循环中,由于FOR的判断指令,加法指令,以及转子程序等等消耗的时间很长,远远大于一个NOP的指令,此时,若要获得执行代码的精确时间,最好用示波器观察,再得出最直接的结果;

在单片机的使用中,不要用浮点数,全部用整数代替,在数据进行移位作乘法时,一定要注意数据有没有越界,算出来的数很容易出现错误,并且在出现浮点数时,可以将数据放大到一定的精度,然后在显示时,将小数点移到对应的位置即可;

在数据做乘法容易越界时,一般将其赋给一个字节多的整数,作为中间变量运算,在确保数据不会越界后,再将其赋给最后结果;

初始化时序

DS18B20

初始化时序步骤:

1. 主机将端口设为输出,先发送一个高电平,然后再拉低,维持480-960US;(推荐500-600US)

2. 主机将端口设为输入,上拉电阻此时将电平拉高,主机等待60US-200US;(推荐100-150US)

3. 主机读取端口数据,低电平则初始化成功;高电平表示初始化失败;

4.读取数据完毕后,主机等待至少400US; (推荐450-500US)

注:

l 第四步很重要,读取初始化状态后,仍然延时400US才可以初始化完毕,否则传感器不能正常使用;

l 在这里注意端口需要不停地改变方向;在主机发送时,设为输出,主机接收时,设为输出;

/*****************18B20的初始化程序***************************/

byte INIT_18B20() {

byte DQ_RETURN=2;

DQ_OUT=1; //引脚设置为输出

DQ=1;

DELAY1(); //稍微延时,即可

DQ=0; //将电平拉低至少480uS,最大为960US

DELAY9(70);

DQ_OUT=0;

//设置为输入,设为输入15到60US

DELAY9(6); //等待18B20响应,如果为低电平表示初始化成功,维持60到240 //微秒

DQ_RETURN=DQ;

DELAY9(70); //读完数据后,仍然延时,至少480US

return(DQ_RETURN); //返回值为1,表示失败,返回值为0表示成功

}

端口写数据时序

DS18B20

1. 主机将电平拉高,稍微延时(推荐值:2US),然后拉低电平,产生一个下降沿,表示写数据开始;低电平维持至少1US;(此时推荐2US)

2. 此时,将要写的1或0放在数据线上;(从写数据第一步开始到现在,整个过程在15US之内完成;

3. 然后主机延时等待至少50US;(推荐60US)

4. 主机最后将电平拉高;

5. 每写两位数据之间的间隔要大于1US;

注:

l 在写步骤中,整个过程端口方向均为输出;

这里对时序要求高,最好用示波器调整出精确的时序;

/*****************向18B20写数据********************************/

void WRITE_18B20(unsigned char ch){

byte i;

for(i=0;i《8;i++) {

DQ_OUT=1; //端口设为输出,并给个拉低电平的下降沿

DQ=1;

DELAY1();

DQ=0; //拉低电平,并维持一微秒以上,表示要发送数据

DELAY1();

DELAY1();

//在15US内将要写的电平写在线上

if((ch&0x01)==1) //将数据按位取出,从LSB到MSB依次送出

DQ=1;

else

DQ=0;

ch=ch》》1;

DELAY9(8); //电平维持40US以上,18B20将在此时将数取出

DQ=1;

}

DQ=1; //最后将电平重新拉高

}

读数据时序

DS18B20

1. 主机将电平拉高,稍微延时(推荐2US),然后将电平拉低,产生一个下降沿,表示读数据;这个低电平至少维持1US,此处推荐2US;

2. 将端口方向设为输入,必须在下降沿之后的15US内将端口数据读取;此处推荐端口方向设为输入后,延时5US,读取端口数据;

3. 读取数据完毕后,延时60US即可;

4. 每两个数据位之间间隔大于1US;

注:

在这个时序内,要不断改变端口方向;

如果上拉电阻阻值合理设置,可以小于4.7K欧姆,利于提高时序速度; l

读数据和写数据都是8位,从LSB开始发送;

/***************从18B20取出字符*******************************/

byte READ_18B20(){

byte ch=0;

byte i;

for(i=0;i《8;i++){

DQ_OUT=1; //端口输出

DQ=1;

DELAY1(); //产生下降沿,至少维持一微秒

DQ=0;

DELAY1(); //将端口设为输入,等待读取

DQ_OUT=0; //在15US之内读取数据

ch=ch》》1;

//延时大概5US

DELAY5();

if(DQ)

ch=ch|0x80;

else

ch=ch&0x7f;

DELAY9(8);

//每两个读数据之间间隔要大于60US }

return(ch); //返回读到的数据

}

以上三段为底层基本函数;DELAY后面的数字DELAY1,DELAY5,DELAY9为延时的微秒时长; DQ设置为硬件连接的端口,DQ_OUT为端口方向的设置

然后就是调用函数了:

当数据线上还有一个18B20时,通常步骤如下:

初始化;

跳过ROM;

温度开始转换命令;

等待温度转换完成;//当使用18B20默认的12位转换精度,用时750MS,经检验,一般耗时比理论稍长;

初始化;

跳过ROM;

读暂存器命令;

将温度数据低八位,高八位依次取出;

初始化;//注:最后仍然要进行初始化

结束;

对应的函数如下

/********************温度开始转换命令程序*******************************/

byte TEMP_DETECT_18B20(){

byte dummy=2;

dummy=INIT_18B20(); //初始化

if(dummy==0){

WRITE_18B20(0XCC); //跳过ROM,不读地址,直接通讯

WRITE_18B20(0x44); //温度开始转换命令

}

return(dummy); //返回0表示成功初始化,开始转换温度

}

注:在开始转换命令和读取温度之间,若18B20忙于转换温度,电平为低电位;

转换完毕将电平拉高;若不想用DELAY等待温度转换,可读取DQ值,为1则表示转换完毕,可以开始读取数据了;

/****************读取温度命令程序***************************************/

uint TEMP_READ_18B20(){

byte dummy=0;

byte TEMH=0,TEML=0;

uint TEM_RESULT;

dummy=INIT_18B20(); //初始化

if(dummy==0){

WRITE_18B20(0XCC); //跳过ROM

WRITE_18B20(0xBE); //读暂存存储器的值命令

TEML=READ_18B20();

TEMH=READ_18B20(); //读温度的高8位和低八位

dummy=INIT_18B20(); //最后初始化,表示读取温度结束

}

TEM_RESULT=(TEML》》3)+(TEMH《《5); //分辨率为0.5°

TEM_RESULT=TEM_RESULT*5;

if((TEMH&0X80)!=0)

//最高位为1,则为负温度 ;;

// TEM_RESULT=~TEMP_RESULT+1; //温度为负,取补码

return(TEM_RESULT); //返回值为温度的十倍,小数点后一位

}

主函数中调用:

SIGNAL=TEMP_DETECT_18B20();

if(SIGNAL==0){

if(DQ) //此时端口为1,则表示转换完成

TEMP_RESULT=TEMP_READ_18B20(); //返回温度的十倍值

若时序错误,很有可能读出的数据位0XFF;若温度传感器烧坏,容易读到85°; l

使用默认12位转换精度,分辨率为0.0625°,此处不需要这么高的精度因此:

TEM_RESULT=(TEML》》3)+(TEMH《《5); //分辨率为0.5°

舍弃后面三位数据,并且只有11位是温度值,高八位中的前五位是符号位;

读取为1时温度为负;读取为0时,温度为正;

DS18B20

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
评论(0)
发评论
电子小白董龙澳 2019-07-17
0 回复 举报
为什么我试了不行,许多错误 收起回复

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分