//***************************************************************** /* 程序功能:在1602液晶屏上顯示當(dāng)前溫度 涉及芯片:1602液晶、SD18b20溫度傳感器 */ //***************************************************************** #include<reg52.h> #define uint unsigned int #define uchar unsigned char sbit DQ=P0^3; sbit rs=P2^0; sbit rw=P2^1; sbit en=P2^2; uchar low,high; //====================================函數(shù)聲明 //*********sd18b20******************* void delayus(uint time); void init_18b20(); void write_18b20(uchar date); uchar read_18b20(); void wndu(); //**********1602液晶************** void init_1602(); void write_com1602(uchar com); void write_date1602(uchar date); //==================================== void delayms(uint time)//毫秒級(jí)延時(shí)函數(shù) { uint i,j; for(i=time;i>0;i--) for(j=110;j>0;j--); } void delayus(uint time)//微秒級(jí)延時(shí)函數(shù) { while(time--); } void init_18b20()//對(duì)sd18b20的初始化 { uchar n; DQ=1; delayus(8); DQ=0; delayus(80); DQ=1; delayus(8); n=DQ; delayus(8); } /*將數(shù)據(jù)線(xiàn)拉為低電平產(chǎn)生寫(xiě)時(shí)間片,在數(shù)據(jù)線(xiàn)口拉為低電平在15微秒到60微秒間對(duì)數(shù)據(jù) 線(xiàn)進(jìn)行數(shù)據(jù)采樣.如果為高電平則為寫(xiě)“1”,如果為低電平則為寫(xiě)零。 對(duì)于主機(jī)產(chǎn)生的寫(xiě)“1”時(shí)間片的情況:數(shù)據(jù)線(xiàn)必須必先拉為低電平,然后被釋放,是 數(shù)據(jù)線(xiàn)在產(chǎn)生時(shí)間片15微秒之內(nèi)拉至高電平; 對(duì)于主機(jī)產(chǎn)生的寫(xiě)“0”時(shí)間片的情況:數(shù)據(jù)線(xiàn)必須被拉至邏輯電平并且保持低電平60個(gè)微秒*/ void write_18b20(uchar com) { uint i; for(i=0;i<8;i++) { DQ=0; //delayus(4); DQ=com&0x01; delayus(10); DQ=1; com>>=1; delayus(4); } delayus(4); } /*從ds18b20讀數(shù)據(jù)時(shí),主機(jī)產(chǎn)生讀時(shí)間片。當(dāng)主機(jī)把數(shù)據(jù)線(xiàn)從邏輯高電平拉至低電平時(shí),產(chǎn)生 讀時(shí)間片。數(shù)據(jù)線(xiàn)必須保持在邏輯低電平至少1個(gè)微秒。來(lái)至ds18b20的數(shù)據(jù)在讀時(shí)間下降沿之 后15微秒有效。因此,為了讀出從時(shí)間片開(kāi)始15微秒的狀態(tài),主機(jī)必須停止保持?jǐn)?shù)據(jù)線(xiàn)為邏輯 低電平。*/ uchar read_18b20() { uint i; uchar date=0x00; for(i=0;i<8;i++) { DQ=0; date>>=1; DQ=1; if(DQ)date|=0x80; delayus(4); DQ=1; delayus(4); } return date; } void wendu() { init_18b20(); write_18b20(0xcc);//跳過(guò)ROM write_18b20(0x44);//啟動(dòng)溫度測(cè)量 delayus(300); init_18b20(); write_18b20(0xcc);//跳過(guò)ROM write_18b20(0xbe);//讀取溫度 low=read_18b20(); //先讀低八位 high=read_18b20();//后讀高八位 } void xianshi() { uchar a,b,c,d; float m,n=0.0625; high<<=4; high+=(low&0xf0)>>4; m=(low%10)*n; delayus(4); write_com1602(0x80+0x03); a=high/10; //顯示十位上的數(shù) write_date1602(0x30+a); delayms(5); write_com1602(0x80+0x04); b=high%10; //顯示個(gè)位上的數(shù) write_date1602(0x30+b); delayms(5); write_com1602(0x80+0x06); c=(int)(m*10); //小數(shù)點(diǎn)后一位 write_date1602(0x30+c); delayms(5); d=(int)(m*100)%10; //小數(shù)點(diǎn)后第二位 write_com1602(0x80+0x07); write_date1602(0x30+d); delayms(5); write_com1602(0x80+0x08); write_date1602(0x27); delayms(5); write_com1602(0x80+0x09); write_date1602('C'); delayms(5); write_com1602(0x80+0x05); write_date1602(0x2e); delayms(5); } void main() { init_1602(); while(1) { wendu(); xianshi(); } } void init_1602() { en=0; rw=0; write_com1602(0x28); delayms(5); write_com1602(0x01); delayms(5); write_com1602(0x0c); delayms(5); write_com1602(0x06); delayms(5); } void write_com1602(uchar com) { uchar gao,di; gao=com&0xf0; di=(com<<4)&0xf0; delayms(5); P2=gao; rs=0; delayms(5); en=1; delayms(5); en=0; delayms(5); P2=di; rs=0; delayms(5); en=1; delayms(5); en=0; delayms(5); } void write_date1602(uchar date) { uchar gao,di; gao=date&0xf0; di=(date<<4)&0xf0; delayms(5); P2=gao; rs=1; delayms(5); en=1; delayms(5); en=0; delayms(5); P2=di; rs=1; delayms(5); en=1; delayms(5); en=0; delayms(5); }