基于AT89C51,DS18B20和1602液晶屏的温度传感器DS18B20与51单片机的连接非常简单,只须把DS18B20的数据线DQ与51单片机的一根并口线连接即可,51单片机通过这根并口就能实现对DS18B20的所有操作,这根并口线一般通过电阻接电源。DS18B20的电源可采用外部电源供电,也可采用内部寄生电源供电。当外部电源供电时,VDD接外部电源,GND接地地。当采用内部寄生电源供电时,VDD与GND一起接地。另外,也可用多片DS18B20连接组网形成多点测温系统,在多片连接时,DS18B20必须采用外部电源供电方式。C语言程序://晶振为12MHz//测量的温度范围-55℃~+99℃,温度精确到小数点后一位#includeREG52.H#defineucharunsignedchar#defineuintunsignedintsbitDQ=P1^0;//定义端口sbitRS=P1^7;sbitRW=P1^6;sbitEN=P1^5;union{ucharc[2];uintx;}temp;ucharflag;//flag为温度值的正负号标志单元,1表示为负值,0时表示为正值。uintcc,cc2;//变量cc中保存读出的温度值floatcc1;ucharbuff1[13]={temperature:};ucharbuff2[6]={+00.0};//检查忙函数voidfbusy(){P2=0xff;RS=0;RW=1;EN=1;EN=0;while((P2&0x80)){EN=0;EN=1;}}//写命令函数voidwc51r(ucharj){fbusy();EN=0;RS=0;RW=0;EN=1;P2=j;EN=0;}//写数据函数voidwc51ddr(ucharj){fbusy();//读状态;EN=0;RS=1;RW=0;EN=1;P2=j;EN=0;}voidinit(){wc51r(0x01);//清屏wc51r(0x38);//使用8位数据,显示两行,使用5*7的字型wc51r(0x0c);//显示器开,光标开,字符不闪烁wc51r(0x06);//字符不动,光标自动右移一格}voiddelay(uintuseconds)//延时程序{for(;useconds0;useconds--);}ucharow_reset(void)//复位{ucharpresence;DQ=0;//DQ低电平delay(50);//480msDQ=1;//DQ高电平delay(3);//等待presence=DQ;//presence信号delay(25);return(presence);//0允许,1禁止}ucharread_byte(void)//从单总线上读取一个字节{uchari;ucharvalue=0;for(i=8;i0;i--){value=1;DQ=0;DQ=1;delay(1);if(DQ)value|=0x80;delay(6);}return(value);}voidwrite_byte(ucharval)//向单总线上写一个字节{uchari;for(i=8;i0;i--)//一次写一字节{DQ=0;DQ=val&0x01;delay(5);DQ=1;val=val/2;}delay(5);}voidRead_Temperature(void)//读取温度{ow_reset();write_byte(0xCC);//跳过ROMwrite_byte(0xBE);//读temp.c[1]=read_byte();temp.c[0]=read_byte();ow_reset();write_byte(0xCC);write_byte(0x44);//开始return;}voidmain()//主程序{uchark;delay(10);EA=0;flag=0;init();wc51r(0x80);//写入显示缓冲区起始地址为第1行第1列for(k=0;k13;k++)//第一行显示提示信息currenttempis:{wc51ddr(buff1[k]);}while(1){delay(10000);Read_Temperature();//读取双字节温度cc=temp.c[0]*256.0+temp.c[1];if(temp.c[0]0xf8){flag=1;cc=~cc+1;}elseflag=0;cc1=cc*0.0625;//计算出温度值cc2=cc1*100;//放大100倍,放在整型变量中便于取数字buff2[1]=cc2/1000+0x30;if(buff2[1]==0x30)buff2[1]=0x20;//取出十位,转换成字符,如果十位是0不显示。buff2[2]=cc2/100-(cc2/1000)*10+0x30;//取出个位,转换成字符buff2[4]=cc2/10-(cc2/100)*10+0x30;//取出小数点后一位,转换成字符if(flag==1)buff2[0]='-';elsebuff2[0]='+';wc51r(0xc5);//写入显示缓冲区起始地址为第2行第6列for(k=0;k6;k++)//第二行显示温度{wc51ddr(buff2[k]);}}}