#include"reg52.h"
#include"intrins.h" #define unchar unsigned char #define unint unsigned int sbit LS138A=P2^2; //管腳定義 sbit LS138B=P2^3; sbit LS138C=P2^4; unsigned char code Disp_Tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; unsigned long LedOut[4]; unsigned int temple; void delay2ms(void) //誤差 0us
{ unsigned char a,b; for(b=4;b>0;b--) for(a=248;a>0;a--); _nop_(); //if Keil,require use intrins.h } sbit DQ=P3^7; //DS18B20部分函數(shù)變量 unchar tempL,tempH; unint tmp; void reset(); void writechar(unchar dat); unint readchar(); unint readtemperature(); void delay(unint t); //液晶部分函數(shù)和變量 void delay1(); unint tt; void wrcmd(unchar cmd); void wrdata(unchar date); void display(); void lcdchus(); void time(unint t); unchar temp2[]={"temperature:"}; unchar temp3[]={"000.0"}; //數(shù)碼管部分 //sbit sda=P0^2; //sbit scl=P0^3; //sbit inter=P3^2; //unint n; //void shift(); //unchar code table[]={0x88}; /****************************************************** 寫DS18B20開始 *******************************************************/
/******************************** 延時子函數(shù) ********************************/ void delay(unint t) {
unint n; n=0; while(n<t) { n++; } } /******************************** DS18B20復(fù)位函數(shù) ********************************/ void reset() { DQ=1; //DQ先置高 delay(8); //延時 DQ=0; //發(fā)送復(fù)位脈沖 delay(85); //延時(>480us) DQ=1; //拉高數(shù)據(jù)線 delay(14); //等待(15~60us)這里是等待DS18B20做出回應(yīng),,如果回應(yīng)DQ將變低, //MCU是在DQ拉高后開始監(jiān)視DQ的值的。 } /******************************** DS18B20寫一個字節(jié)函數(shù) ********************************/ void writechar(unchar dat) { unint i; for(i=8;i>0;i--) { DQ=0; //先將DQ拉低,,我們這里先不延時15us先,,在下面的 delay(5)一起延了, //因為時序圖它是一直保持低電平的 DQ=dat&0x01;//去數(shù)據(jù)的最低位,,應(yīng)為DS18B20是從低到高讀的 delay(5);//延時在60-120us之間 DQ=1; //將DQ拉高 dat>>=1;//右移一位 } delay(4);//這里延時1us以上 } /******************************** DS18B20讀一個字節(jié)函數(shù) ********************************/ unint readchar() { unchar i,dat=0;//這里要付初值 for (i=8;i>0;i--) { DQ=1; //DQ稍微拉高,,這不可有可無 delay(1);//延時小會,這里延時不嚴(yán)格 DQ=0; //按照時序圖,,將DQ拉低,先不延時,,在下面delay(4)在一起延! dat>>=1;//右移一位 DQ=1; //釋放一下總線,等待檢查DQ值,! if(DQ)//當(dāng)DQ為1是執(zhí)行下面,,如果DQ為0,值不變,。你們想一下,。。 dat=dat|0x80;//把低位先放在高位,,然后右移8次,,高位的數(shù)據(jù)就移到了低位,因為我們是先寫低位的,! delay(4);//延時60-120us吧,。。 } return(dat);//返回dat值 } /******************************** DS18B20讀溫度程序 ********************************/ unint readtemperature() { unint temperature; reset(); //初始化 writechar(0xcc); //寫SKIP ROM(跳過檢查ROM序列,,因為我們一般只有一個DS18B20?。?br> writechar(0x44); //寫啟動溫度轉(zhuǎn)換 delay(125); //轉(zhuǎn)換需要一點時間,延時大一點,,應(yīng)該大于500us吧 reset(); //初始化 writechar(0xcc); //寫SKIP ROM(跳過檢查ROM序列,,因為我們一般只有一個DS18B20!) writechar(0xbe); //讀溫度寄存器RAM(頭兩個值分別為溫度的低位和高位) tempL=readchar(); //讀出溫度的低位LSB tempH=readchar(); //讀出溫度的高位MSB //溫度轉(zhuǎn)換,,把高低位做相應(yīng)的運算轉(zhuǎn)化為實際溫度 temperature=((tempH*256)+tempL)*0.0625*10+0.5;//tempH*256的意思是tempH向左移8位 delay(200);//兩次間隔轉(zhuǎn)換的間隔要延時一下 return(temperature); } void display(void)
{ unsigned char i=0; unsigned char A, B ,C; A= temple/100; B= temple%100/10; C= temple%10; LedOut[0]= Disp_Tab[A]; LedOut[1]= Disp_Tab[B]; LedOut[2]= Disp_Tab[C]; for(i=0;i<4;i++) { P0 = LedOut[i] ; switch(i) { case 0:LS138A=0; LS138B=0; LS138C=0; break; case 1:LS138A=1; LS138B=0; LS138C=0; break; case 2:LS138A=0; LS138B=1; LS138C=0; break; case 3:LS138A=1; LS138B=1; LS138C=0; break; } delay2ms(); } } void main(void)
{ while(1) { unsigned char i; i=0; temple=readtemperature() ; for(i=0;i<200;i++) { display(); } }} |
|