//读者须知://若要用这个程序,LCD的D0-D7跟单片机的P2口连。LCD用得是1602,LCD的第4脚与单片机的P3.5脚,LCD的第6脚与单片机的P3.4连//LCD的第5脚接地。DS18B20的数据线(中间的引脚)接单片机的P1.0。单片机用的是AT89S52.//这个程序,本人测试过了,测试过单总线上7个DS18B20的连接,并能正确读到。////序列号只能一位一位读出来,先写个程序读出序列号,然后可以针对某一个DS18B20进行操作//需要注意的是:若单总线上有多个DS18B20时,读不到正确的序列号,因为单片机在总线上发出读序列号的命令后//每一个DS18B20都会开始上传自己的序列号,因此读不到正确的序列号,只能一个一个地读序列号。#includereg52.h#includestdio.h#defineucharunsignedchar#defineuintunsignedintsbitds=P1^0;//温度传感器DS18B20信号线与P1.0连uinttemp,temp1,temp2,temp3,temp4,temp5,temp6,temp7,temp8,num,num1;floatf_temp;ucharD1_ROM_ID[8];ucharD2_ROM_ID[8];//通过调用“read_and_display_DS18B20_ROMID()”在1602液晶里显示序列号,如何读到正确的序列号,请//参考read_and_display_DS18B20_ROMID()的说明,读出正确的序列号后,把序列号填到下面的数组里面,//然后通过调用“get_temperature(DD1_ROM_ID)”得到总线上指定的DS18B20的温度,而不会读到其它的DS18B20的温度。//需要注意的是:若单总线上有多个DS18B20时,读不到正确的序列号,因为单片机在总线上发出读序列号的命令后//每一个DS18B20都会开始上传自己的序列号,因此读不到正确的序列号,只能一个一个地读序列号。ucharcodeDD1_ROM_ID[8]={0x28,0x0b,0x0f,0x0d,0x02,0x00,0x00,0x5b};ucharcodeDD2_ROM_ID[8]={0x28,0xc1,0xdc,0x0c,0x02,0x00,0x00,0x94};//液晶1602部分--startsbitLCDen=P3^4;//液晶LCD1602的第6脚与P3.4连sbitLCDrs=P3^5;//液晶LCD1602的第4脚与P3.5连unsignedcharcodetable[]=ILOVEMCU!;unsignedcharcodetable1[]=液晶1602部分--end//延时xms毫秒voiddelay(uintxms){uinti,j;for(i=xms;i0;i--)for(j=120;j0;j--);}//R/W--GND,noused液晶的第5脚没有用到,直接接地。因为往液晶里写数据就显示,所以只需要接地。//不需要从液晶里读数据,所以这根脚就直接接地。//往液晶里写命令:如清屏,设置显示的位置等。voidwrite_com(ucharcom){LCDrs=0;P2=com;delay(5);LCDen=1;delay(5);LCDen=0;}//往液晶里写数据:要显示的数据,通过此程序来写进液晶里去。voidwrite_data(uchardate){LCDrs=1;P2=date;delay(5);LCDen=1;delay(5);LCDen=0;}//液晶部分--start:1602的初始化voidLCD_init(){write_com(0x38);//P150,tale7.2.6write_com(0x0c);//opendisplay,notdisplaycursorwrite_com(0x06);//addresspointaddoneafterwriteacharwrite_com(0x01);//cleartheLCDanddatapoint}//液晶部分--end:1602的初始化//DS18B20的相关程序--startvoiddsreset(void)//DS18B20复位,初始化函数{uinti;ds=1;i++;ds=0;i=400;while(i0)i--;ds=1;//i=4;i=8;while(i0)i--;}bittempreadbit(void)//读1位数据函数{uinti;bitdat;ds=1;i++;ds=0;i++;i++;i++;i++;ds=1;i++;i++;dat=ds;i=30;while(i0)i--;//i=8;while(i0)i--;;若是i=8,只能检测到5个3return(dat);}uchartempread(void)//读1个字节数据函数{uchari,j,dat;dat=0;for(i=1;i=8;i++){j=tempreadbit();dat=(j7)|(dat1);}returndat;}voidtempwritebyte(uchardat)//向DS18B20写一个字节数据函数{uinti;ucharj;bittestb;for(j=1;j=8;j++){testb=dat&0x01;dat=dat1;if(testb){ds=0;i++;i++;ds=1;i=8;while(i0)i--;}else{ds=0;i=8;while(i0)i--;ds=1;i++;i++;}}}voidtempchange(void)//DS18B20开始获取温度并转换{dsreset();delay(1);tempwritebyte(0xcc);tempwritebyte(0x44);}//只有一个DS18B20的时候可以用这个子程序得到温度uintget_temp(void)//读取寄存器中存储的温度数据{uchara,b;dsreset();delay(1);tempwritebyte(0xcc);tempwritebyte(0xbe);a=tempread();b=tempread();temp=b;temp=temp8;temp=temp|a;f_temp=temp*0.0625;temp=f_temp*100+0.5;//乘*100表示小数点后面取2位,加0.5是四舍五入returntemp;}uintget_temperature(unsignedcharP_ROM_ID[8])//读取寄存器中存储的温度数据{uchara,b;uchar*p;p=P_ROM_ID;dsreset();delay(5);tempwritebyte(0x55);//匹配ROMfor(a=0;a8;a++){tempwritebyte(*p);++p;}delay(5);tempwritebyte(0xbe);//读温度a=tempread();b=tempread();temp=b;temp=temp8;temp=temp|a;f_temp=temp*0.0625;temp=f_temp*100+0.5;//乘*100表示小数点后面取2位,加0.5是四舍五入returntemp;}voiddis_temp(uintt)//显示温度值函数{uinti;i=t/10000;write_data(i+0x30);i=t%10000/1000;write_data(i+0x30);i=t%10000%1000/100;write_data(i+0x30);write_data('.');//显示小数点i=t%10000%1000%100/10;write_data(i+0x30);//i=t%10000%1000%100%10;//若需要显示第二位小数点,就把这里两行的注释取消就可以了。//write_data(i+0x30);}//得到ROM_ID(DS18B20的序列号)voidini_and_get_ROM_ID(void){uchari;dsreset();delay(1);tempwritebyte(0x33);//读ROMfor(i=0;i8;i++){D1_ROM_ID[i]=tempread();delay(5);}}//显示序列号的,通过LCD去显示,读出来的是ASCII码,减去0x30.//比如:其中读到是?,对应ASCII是0x3f,所以减去0x30,即为f//ucharcodeDD1_ROM_ID[8]={0x28,0x0b,0x0f,0x0d,0x02,0x00,0x00,0x5b};//ucharcodeDD2_ROM_ID[8]={0x28,0xc1,0xdc,0x0c,0x02,0x00,0x00,0x94};//是读出来的,序列号只能一位一位读出来//需要注意的是:若单总线上有多个DS18B20时,读不到正确的序列号,因为单片机在总线上发出读序列号的命令后//每一个DS18B20都会开始上传自己的序列号,因此读不到正确的序列号,只能一个一个地读序列号。voidread_and_display_DS18B20_ROMID(void){uchardel,del1;//得到ROM_ID;ini_and_get_ROM_ID();write_com(0x80+0x40);del=D1_ROM_ID[0];del1=del/16;write_data(del1+0x30);del1=del%16;write_data(del1+0x30);del=D1_ROM_ID[1];del1=del/16;write_data(del1+0x30);del1=del%16;write_data(del1+0x30);del=D1_ROM_ID[2];del1=del/16;write_data(del1+0x30);del1=del%16;write_data(del1+0x30);del=D1_ROM_ID[3];del1=del/16;write_data(del1+0x30);del1=del%16;write_data(del1+0x30);del=D1_ROM_ID[4];del1=del/16;write_data(del1+0x30);del1=del%16;write_data(del1+0x30);del=D1_ROM_ID[5];del1=del/16;write_data(del1+0x30);del1=del%16;write_data(del1+0x30);del=D1_ROM_ID[6];del1=del/16;write_data(del1+0x30);del1=del%16;write_data(del1+0x30);del=D1_ROM_ID[7];del1=del/16;write_data(del1+0x30);del1=del%16;write_data(del1+0x30);del=D1_ROM_ID[8];del1=del/16;write_data(del1+0x30);del1=del%16;write_data(del1+0x30);}//DS18B20的相关程序--endvoidmain(){uchardel,del1;temp=0;temp1=0;temp2=0;LCD_init();//测试液晶用的write_com(0x80);//thedatastartat0x80.reftotable7.2.4for(num=0;num11;num++){write_data(table[num]);delay(5);}//displaythesecondrowwrite_com(0x80+0x40);for(num=0;num14;num++){write_data(table1[num]);de