//***************************************************************** /* 程序功能:在1602液晶屏上顯示當前溫度 涉及芯片: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; //====================================函數聲明 //*********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)//毫秒級延時函數 { uint i,j; for(i=time;i>0;i--) for(j=110;j>0;j--); } void delayus(uint time)//微秒級延時函數 { while(time--); } void init_18b20()//對sd18b20的初始化 { uchar n; DQ=1; delayus(8); DQ=0; delayus(80); DQ=1; delayus(8); n=DQ; delayus(8); } /*將數據線拉為低電平產生寫時間片,在數據線口拉為低電平在15微秒到60微秒間對數據 線進行數據采樣.如果為高電平則為寫“1”,如果為低電平則為寫零。 對于主機產生的寫“1”時間片的情況:數據線必須必先拉為低電平,然后被釋放,是 數據線在產生時間片15微秒之內拉至高電平; 對于主機產生的寫“0”時間片的情況:數據線必須被拉至邏輯電平并且保持低電平60個微秒*/ 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讀數據時,主機產生讀時間片。當主機把數據線從邏輯高電平拉至低電平時,產生 讀時間片。數據線必須保持在邏輯低電平至少1個微秒。來至ds18b20的數據在讀時間下降沿之 后15微秒有效。因此,為了讀出從時間片開始15微秒的狀態,主機必須停止保持數據線為邏輯 低電平。*/ 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);//跳過ROM write_18b20(0x44);//啟動溫度測量 delayus(300); init_18b20(); write_18b20(0xcc);//跳過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; //顯示十位上的數 write_date1602(0x30+a); delayms(5); write_com1602(0x80+0x04); b=high%10; //顯示個位上的數 write_date1602(0x30+b); delayms(5); write_com1602(0x80+0x06); c=(int)(m*10); //小數點后一位 write_date1602(0x30+c); delayms(5); d=(int)(m*100)%10; //小數點后第二位 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); }