基于AT89C51的DS18B20温度传感器读写程序
#include <intrins.h> sbit DQ=P1^0; //温度传感器数据线接口 //DS18B20初始化 bit DS18B20Init(void) { unsigned int i,j; DQ=1; //(1) 先将数据线置高电平“1”。 _nop_(); //(2) 延时(该时间要求的不是很严格,但是尽可能的短一点) DQ=0; //(3) 数据线拉到低电平“0”。 for(i=0;i<750;i++) _nop_(); //(4) 延时750微秒(该时间的时间范围可以从480到960微秒) DQ=1; //(5) 数据线拉到高电平“1”。 for(i=0;i<540;i++) //(6) 延时等待(如果初始化成功则在15到60微秒时间之内产生一个由DS18B20所返回的低电平“0”。 { _nop_(); if(DQ==0) {P3=0x00;break;} else continue; } if(i>=60) return 1; //初始化失败 for(j=i;j<540-i;j++) _nop_(); //(7) 若CPU读到了数据线上的低电平“0”后,还要做延时, //其延时的时间从发出的高电平算起(第(5)步的时间算起)最少要480微秒。 DQ=1; //(8) 将数据线再次拉高到高电平“1”后结束。 _nop_(); return 0; //初始化成功 } //发送一个字节的数据 void WriteDat(unsigned char dat) { unsigned char i,j; ACC=dat; for(i=0;i<8;i++) { DQ=1; switch(ACC&0x01) { case 0: //写0 { DQ=0; for(j=0;j<30;j++) _nop_(); break; } case 1: //写1 { DQ=0; _nop_(); DQ=1; for(j=0;j<30;j++); _nop_(); break; } } for(j=0;j<15;j++) _nop_(); ACC=ACC>>1; //下一位 } DQ=1; _nop_(); } //读一个字节的数据 unsigned char ReadDat(void) { unsigned char temp=0x00; unsigned char i,j; for(i=0;i<8;i++) { DQ=1; _nop_(); DQ=0; for(j=0;j<15;j++) _nop_(); DQ=1; _nop_(); F0=DQ; if(F0) ACC=0x80; else ACC=0x00; temp=ACC|0xff; temp=temp>>1; for(j=0;j<30;j++) _nop_(); } return temp; } //Temperature计算,把从RAM中读出的数计算成一个完整的可以用于表示当前温度的值 ////如果温度是0度下则最高位为1,否则为0 float TempCal(unsigned char TPH,unsigned char TPL) { unsigned char TempDat[2];//第一位是整数部分,第二位是小数部分 float Temp; TempDat[0]=(((TPL&0xf0)>>4)|((TPH&0x0f)<<4)); //取整数 TempDat[1]=TPL&0x0f; //取小数 if(TPH&0xf8) { TempDat[0]=~TempDat[0]; TempDat[1]=(TempDat[1]^0x0f)+0x01; Temp=((float)(TempDat[0]|0x80)+(float)TempDat[1]*0.0625); } else Temp=(float)TempDat[0]+(float)TempDat[1]*0.0625; return Temp; } float StartTemp(void) { unsigned char RamDat[9]; unsigned int i; if(DS18B20Init()); //器件复位,如果为1则复位不成功,0则复位成功 return 255; WriteDat(0xcc); //跳过器件匹配 WriteDat(0x44); //启动温度转换 for(i=0;i<900;i++) _nop_(); WriteDat(0xbe); for(i=0;i<9;i++) //读RAMD数据 RamDat[i]=ReadDat(); return TempCal(RamDat[1],RamDat[0]); }
凯特网版权声明:以上内容允许转载,但请注明出处,谢谢!