#include <AT89X52.H> unsigned char TPLSB,TPMSB; //温度的低位,高位字节 sbit DQ=P3^5; //数据通讯接口 /*程序延时T毫秒*/ void delay(unsigned char t) { unsigned char i; while(t--) { for(i=0;i<125;i++) { } } } /*产生复位脉冲初始化DS18B20*/ void TXreset (void) { unsigned char i; DQ=0; i=100; //拉低900US while(i>0) i--; DQ=1; //产生上升沿 i=4; while(i>0) i--; } /*等待应答脉冲*/ void RXwait (void) { unsigned char i; while (DQ); while (~DQ); //检测到应答脉冲 i=4; while (i>0) i--; } /*读取数据的一位,满足温度的要求*/ bit RDbit (void) { unsigned char i; bit b; DQ=0; i++; //保持低至少1us DQ=1; i++; i++; //延时15US以上,读时钟下降沿后15US,DS18B20输出数据有效 b=DQ; i=8; while (i>0) i--; //读时钟不低于60US return (b); } /*读取数据的一个字节*/ unsigned char RDbyte (void) { unsigned char i,j,b; b=0; for (i=0;i<=8;i++) { j=RDbit(); b=(j<<7)|(b>>1); return (b); } } /*写数据的一个字节*/ void WRbyte (unsigned char b) { unsigned char i; unsigned char j; bit btmp; for (j=1;j<=8;j++) { btmp=b&0x01; b=b>>1; //取下一位由地位到高位 if (btmp) { DQ=0; i++; i++; //延时,使得15US内拉高 DQ=1; i=8; //整个写1的时隙不低于60US while (i>0) i--; } else { DQ=0; //写0 i=8; while (i>0) i--; //保持低在60~120US之间 DQ=1; i++; i++; } } } /*启动温度转换程序*/ void convert (void) { TXreset( ); //产生复位脉冲,初始化DS18B20 RXwait(); //等待DS18B20给出应答脉冲 delay(1); //延时 WRbyte(0xcc); //SKIP ROM命令 WRbyte(0x44); //convert T命令 } /*读取温度值程序*/ void RDtemp(void) { TXreset(); RXwait(); delay(1); WRbyte(0xcc); WRbyte(0xbc); //read scratchpad命令 TPLSB=RDbyte(); //温度的低四位为二进制小数部分,高位值的高字节的高五位为符号位 TPMSB=RDbyte(); } /*主程序,读取温度值最终放在TPLSB,TPMSB变量中通过数码管输出,要进行十进制 有符号数的转换*/ void main(void) { do { delay(1); //延时1MS convert(); //启动温度转换需要750MS RDtemp(); //读取温度值 } while(1); } 程序如上;请指点! |