#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部分函数变量 unchar tempL,tempH; unint tmp; void reset(); void writechar(unchar dat); unint readchar(); unint readtemperature(); void delay(unint t); //液晶部分函数和变量 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"}; //数码管部分 //sbit sda=P0^2; //sbit scl=P0^3; //sbit inter=P3^2; //unint n; //void shift(); //unchar code table[]={0x88}; /****************************************************** 写DS18B20开始 *******************************************************/
/******************************** 延时子函数 ********************************/ void delay(unint t) {
unint n; n=0; while(n<t) { n++; } } /******************************** DS18B20复位函数 ********************************/ void reset() { DQ=1; //DQ先置高 delay(8); //延时 DQ=0; //发送复位脉冲 delay(85); //延时(>480us) DQ=1; //拉高数据线 delay(14); //等待(15~60us)这里是等待DS18B20做出回应,如果回应DQ将变低, //MCU是在DQ拉高后开始监视DQ的值的。 } /******************************** DS18B20写一个字节函数 ********************************/ void writechar(unchar dat) { unint i; for(i=8;i>0;i--) { DQ=0; //先将DQ拉低,我们这里先不延时15us先,在下面的 delay(5)一起延了, //因为时序图它是一直保持低电平的 DQ=dat&0x01;//去数据的最低位,应为DS18B20是从低到高读的 delay(5);//延时在60-120us之间 DQ=1; //将DQ拉高 dat>>=1;//右移一位 } delay(4);//这里延时1us以上 } /******************************** DS18B20读一个字节函数 ********************************/ unint readchar() { unchar i,dat=0;//这里要付初值 for (i=8;i>0;i--) { DQ=1; //DQ稍微拉高,这不可有可无 delay(1);//延时小会,这里延时不严格 DQ=0; //按照时序图,将DQ拉低,先不延时,在下面delay(4)在一起延! dat>>=1;//右移一位 DQ=1; //释放一下总线,等待检查DQ值! if(DQ)//当DQ为1是执行下面,如果DQ为0,值不变。你们想一下。。 dat=dat|0x80;//把低位先放在高位,然后右移8次,高位的数据就移到了低位,因为我们是先写低位的! delay(4);//延时60-120us吧。。 } return(dat);//返回dat值 } /******************************** DS18B20读温度程序 ********************************/ unint readtemperature() { unint temperature; reset(); //初始化 writechar(0xcc); //写SKIP ROM(跳过检查ROM序列,因为我们一般只有一个DS18B20!) writechar(0x44); //写启动温度转换 delay(125); //转换需要一点时间,延时大一点,应该大于500us吧 reset(); //初始化 writechar(0xcc); //写SKIP ROM(跳过检查ROM序列,因为我们一般只有一个DS18B20!) writechar(0xbe); //读温度寄存器RAM(头两个值分别为温度的低位和高位) tempL=readchar(); //读出温度的低位LSB tempH=readchar(); //读出温度的高位MSB //温度转换,把高低位做相应的运算转化为实际温度 temperature=((tempH*256)+tempL)*0.0625*10+0.5;//tempH*256的意思是tempH向左移8位 delay(200);//两次间隔转换的间隔要延时一下 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(); } }} |
|