#include <REGX52.H> #define uchar unsigned char sbit DQ=P2^0; //數據傳輸線接單片機的相應的引腳 unsigned char tempL=0; //臨時變量低位(無符號字符變量) unsigned char tempH=0; //臨時變量高位 unsigned int tempa; //溫度值(整型變量) uchar display_data[4]={0}; void DS18_delay(int useconds)//延時函數 { int s; for (s=0; s<useconds;s++); } unsigned char Init_DS18B20(void) { unsigned char x=0; DQ=0; //發送復位脈沖 DS18_delay(29); //延時(>480ms) DQ=1; //拉高數據線 DS18_delay(3); //等待(15~60ms) 等待存在脈沖 x=DQ; //獲得存在信號(用于判斷是否有器件) DS18_delay(25); // 等待時間隙結束 return(x); //返回存在信號,0 = 器件存在, 1 = 無器件 } ReadOneChar(void)//讀一個字節 { unsigned char i=0; unsigned char dat=0; for (i=8;i>0;i--) { DQ=1; DS18_delay(1); DQ=0; dat>>=1;//復合賦值運算,等效dat=dat>>1(dat=dat右移一位后的值) DQ=1; if(DQ) dat|=0x80; DS18_delay(4); } return(dat); } WriteOneChar(unsigned char dat)//有參函數,功能是"寫",而寫的內容就是括號內的參數 { unsigned char i=0; for(i=8;i>0;i--) { DQ=0; DQ=dat&0x01; DS18_delay(5); DQ=1; dat>>=1;//復合賦值運算,等效dat=dat>>1(dat=dat右移一位后的值) } DS18_delay(4); } unsigned int ReadTemperature(void)//返回讀取的溫度. { Init_DS18B20(); //初始化,調用初始化函數 WriteOneChar(0xcc); //跳過讀序列號的操作,調用寫函數,寫0xcc指令碼(跳過讀序列號) WriteOneChar(0x44); //啟動溫度轉換,調用寫函數,寫0x44指令碼(啟動溫度轉換) DS18_delay(125); //轉換需要一點時間,延時 Init_DS18B20(); //初始化,調用初始化函數 WriteOneChar(0xcc); //跳過讀序列號的操作,調用寫函數,寫0xcc指令碼(跳過讀序列號? WriteOneChar(0xbe); //調用寫函數,寫0xbe指令碼,讀溫度寄存器(頭兩個值分別為溫度的低位和高位) tempL=ReadOneChar(); //讀出溫度的低位LSB tempH=ReadOneChar(); //讀出溫度的高位MSB tempa=((tempH*256)+tempL)*6.25; //溫度轉換,擴大100返回 //DS18_delay(10); //tempa=tempL+tempH; return(tempa);//運算結果返回到函數 } void display()//顯示函數 { unsigned char i,j,k=0x80; unsigned char code dis[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x39}; for(i=0;i<4;i++) { P2=0x0f; if(i==1) P0=dis[display_data[i]]+0x80; else P0=dis[display_data[i]]; P2=k; k=k>>1; for(j=250;j>0;j--); } P2=0x0f; } void main() { unsigned int temp; uchar i; while(1) { temp=ReadTemperature(); display_data[0]=temp/1000; display_data[1]=(temp/100)%10; display_data[2]=(temp/10)%10; display_data[3]=temp%10; for(i=0;i<250;i++) display(); } }