用DS18B20做的电子温度计,非常简单。#include #include\"AscLed.h\"#include #include //********************************************************#define Seck (500/TK) //1秒中的主程序的系数#define OffLed (Seck*5*60) //自动关机的时间5分钟!//********************************************************#if (FHz==0) #define NOP_2uS_nop_()#else #define NOP_2uS_nop_();_nop_()#endif//**************************************#define SkipK 0xcc //跳过命令#define ConvertK 0x44 //转化命令#define RdDs18b20K 0xbe //读温度命令//*******************************************extern LedOut(void);//*************************************************sbit PNP1=P3^4;sbit PNP2=P3^5;sbit BEEP=P3^2;//***********************************#defineDQ PNP2 //原来的PNP2 BEEP//***********************************static unsigned char Power=0;//************************************union{ unsigned char Temp[2]; //单字节温度 unsigned int Tt; //2字节温度}T;//***********************************************typedef struct{ unsigned char Flag; //正数标志 0;1==》负数 unsigned char WenDu; //温度整数 unsigned int WenDuDot; //温度小数放大了10000}WENDU; //***********************************************WENDU WenDu;unsigned char LedBuf[3];//----------------------------------//功能:10us 级别延时// n=1===> 6Mhz=14uS 12MHz=7uS//----------------------------------void Delay10us(unsigned char n){ do{ #if (FHz==1) NOP_2uS;NOP_2uS; #endif }while(--n);}//-----------------------------------//功能:写18B20//-----------------------------------void Write_18B20(unsigned char n){ unsigned char i; for(i=0;i<8;i++){ DQ=0; Delay10us(1);//延时13us 左右 DQ=n & 0x01; n=n>>1; Delay10us(5);//延时50us 以上 DQ=1; }}//------------------------------------//功能:读取18B20//------------------------------------unsigned char Read_18B20(void){ unsigned char i; unsigned char temp; for(i=0;i<8;i++){ temp=temp>>1; DQ=0; NOP_2uS;//延时1us DQ=1; NOP_2uS;NOP_2uS;//延时5us if(DQ==0){ temp=temp&0x7F; }else{ temp=temp|0x80; } Delay10us(5);//延时40us DQ=1; } return temp;}//-----------------------------------void Init (void){ DQ=0; Delay10us(45);//延时500us DQ=1; Delay10us(9);//延时90us if(DQ){ //0001 1111b=1f Power =0; //失败0 }else{ Power++; DQ=1; }}//----------------------------------void Skip(void){ Write_18B20(SkipK); Power++;}//----------------------------------void Convert (void){ Write_18B20(ConvertK); Power++;}//______________________________________void Get_Ds18b20L (void){ T.Temp[1]=Read_18B20(); //读低位 Power++;}//______________________________________void Get_Ds18b20H (void){ T.Temp[0]=Read_18B20(); //读高位 Power++;}//------------------------------------//规范化成浮点数// sssss111;11110000// sssss111;1111(0.5,0.25,0.125,0.0625)//------------------------------------void ReadTemp (void){ unsigned char i; unsigned intF1=0; char j=1; code int Code_F[]={6250,1250,2500,5000}; WenDu.Flag=0; if (T.Temp[0] >0x80){ //负温度 T.Tt =~T.Tt+1; //取反+1=源吗 +符号S WenDu.Flag=-1; } T.Tt <<= 4; //左移4位 WenDu.WenDu=T.Temp[0]; // 温度整数 //************************************************** T.Temp[1]>>=4; //--------------------------- for (i=0;i<4;i++){ //计算小数位 F1 +=(T.Temp[1] & 0x01)*Code_F; T.Temp[1]>>=1; } WenDu.WenDuDot=F1; //温度的小数 Power=0;}//----------------------------------void Delay1S (void){ static unsigned int i=0; if (++i==Seck) {i=0ower++;}}//----------------------------------void ReadDo (void){ Write_18B20(RdDs18b20K); Power++;}/**********************************函数指针定义***********************************/code void (code *SubTemp[])()={ Init,Skip,Convert,Delay1S,Init,Skip,ReadDo,Get_Ds18b20L, Get_Ds18b20H,ReadTemp};//**************************************void GetTemp(void){ (*SubTemp[Power])();}//---------------------------------------------------//将温度显示,小数点放大了10000.void GetBcd(void){ LedBuf[0]=WenDu.WenDu / 10; LedBuf[1]=WenDu.WenDu % 10 +DotK; LedBuf[2]=(WenDu.WenDuDot/1000)%10; if(LedBuf[0]==0)LedBuf[0]=Black; if(WenDu.Flag==0) return; if(LedBuf[0] !=Black){ LedBuf[2]=LedBuf[1]; LedBuf[1]=LedBuf[0]; LedBuf[0]=Led_Pol; //'-' }else{ LedBuf[0]=Led_Pol; //'-' }}/*//---------------------------------------------------void JbDelay (void){ static long i; if (++i>=OffLed){ P1=0xff; P2=0xff; PCON=0x02; }}*//*****************************************************主程序开始1:2002_10_1 设计,采用DS18B20测量2:采用函数数组读取DS18B20.LED数码管显示正常!3:改变FHz可以用6,12MHz工作!******************************************************/code unsigned char Stop[3] _at_ 0x3b;void main (void){ P1=0xff; WenDu.WenDu=0; while (1){ GetTemp(); GetBcd(); // JbDelay(); LedOut(); }}复制代码 20091012_8b1ef92155560c13b5807ZmoDVSacjwD[1].jpg (12 KB) 2009-10-21 23:21 上传下载次数:0