以下为程序: #include<reg51.h> // 51 系类
单片机头文件 #include<intrins.h> #define uint unsigned int #define ucharunsigned char sbitsw=P2^0; //定义升温 sbitjw=P2^1; //定义降温 sbit beep =P2^2; //定义扬声器 sbit SB1=P2^3; sbit SB2=P2^4; sbitrs=P2^5; //lcd的控制 sbit rw=P2^6; sbit e=P2^7; sbit DQ=P1^0; sbit DQ1=P1^1; bit flag=1; uchar T=0,temp1=0,temp2=0,flag_dis=0; uchartable[]={"wait for component.... "}; uchartable1[]={'0','1','2','3','4','5','6','7','8','9'}; uchar table2[]={"T= "}; /******************************************************* 函数:1602 模块******************************************************/void delay(uintz) //延时 { uchar x,y; for(x=50;x>1;x--) for(y=z;y>1;y--); } voidlcd_writecom(uchar com) //写地址函数 { rs=0; rw=0; P0=com; delay(10); e=1; delay(10); e=0; } voidlcd_writedate(uchar dat) //写数据函数 { rs=1; rw=0; P0=dat; delay(1); e=1; delay(1); e=0; } voidinit_1602(void) //1602初始话 { delay(10); lcd_writecom(0x38); delay(5); lcd_writecom(0x38); delay(5); lcd_writecom(0x38); delay(5); lcd_writecom(0x01); delay(5);lcd_writecom(0x08); delay(5); lcd_writecom(0x06); delay(5); lcd_writecom(0x0C); } /****************************************************** * 函数:18B20 模块* *******************************************************/ bit init_DS18B20(void) //18b20初始化程序 { bit flag; uchar
time; DQ=1; _nop_(); DQ=0; //再将数据线从高拉低,要求保持480~960us for(time=0;time<200;time++) //略微延时约600微秒//以向DS18B20发出 //一持续480~960us的低电平复位脉冲 DQ=1; //释放数据线(将数据线拉高) for(time=0;time<20;time++); //延时约60us(释放总线后需等待15~60usDS18B20 //输出存在脉冲) flag=DQ; //让单片机检测是否输出了存在脉冲(DQ=0表示存在) for(time=0;time<200;time++); //延时足够长时间,等待存在脉冲输出完毕 return(flag); //返回检测成功标志 } void WriteOneChar ( uchar dat) //18B20 写数据 { uchar i,time; for (i=0; i<8; i++) { DQ=1; _nop_(); DQ=0; //将数据线从高拉低时即启动写时序 for(time=0;time<1;time++);DQ=dat&0x01; //利用与运算取出要写的某位二进制数据,并将其送到数据线上等DS18B2采样 for(time=0;time<10;time++);//延时约30us,DS18B20在拉低后的约15~60us期间从//////数据线上采样 DQ=1; //释放数据线 for(time=0;time<1;time++) //延时3us,两个写时序间至少需要1us的恢复期 dat>>=1; //将dat中的各二进制位数据右移1位 } } ucharReadOneChar(void) //18B20 读数据 { uchar time,i,date=0; //储存读出的一个字节数据 for (i=0;i<8;i++) { DQ=1; _nop_(); DQ = 0; //单片机从DS18B20读书据时,将数据线从高拉低即启动读时序for(time=0;time<1;time++); //等待一个机器周期 DQ = 1; //将数据线"人为"拉高,为单片机检测DS18B20的输出电平作准////备 for(time=0;time<2;time++); //延时约6us,使主机在15us内采样 date>>=1; if(DQ==1) date|=0x80; //如果读到的数据是1,则将1存入dat else date|=0x00; //如果读到的数据是0,则将0存入dat for(time=0;time<15;time++); //延时3us,两个读时序之间必须有大于1us的恢复期 } return(date); //返回读出的十六进制数据 } void tempchange_get(void) //启动18B20温度转换+ 读取数据 { uchara,b[3],p,time,tempL,tempH; init_DS18B20(); //18B20 复位 WriteOneChar(0xcc); //跳过读ROM 指令 WriteOneChar(0x44); //写温度转换指令 delay(10); init_DS18B20(); //准备读数据的初始化 for(time=0;time<2;time++); WriteOneChar(0xcc); //跳过ROM WriteOneChar(0xbe); //读暂存器 tempL = ReadOneChar(); //读低8 位 tempH = ReadOneChar(); //读高8 位 a=tempH&0x80; if(a) //为一则是负温度,补码修正,为零则是正温度,不处理 { if(tempL==0){tempH--;tempL=255;}tempL-=1; tempL=~tempL; tempH=~tempH; flag_dis=1; } else flag_dis=0; //对取出的数据处理 temp1=tempL&0x0F; //取第一字节低四位 b[0]=temp1&0x08; b[1]=temp1&0x04; b[2]=temp1&0x02; b[3]=temp1&0x01; b[0]>>=3; b[1]>>=2; b[2]>>=1; p=b[0]*5000+b[1]*2500+b[2]*1250+b[3]*625; //小数位化整数 temp2=p/1000; //第一个小数位 tempL&=0xF0; //取第一字节高四位 tempL>>=4; temp1=tempH&0x0F; //取第二字节低四位 temp1<<=4; temp1=temp1&0x7F; //只取7位 temp1=temp1|tempL; //合并为整数位数据 } /******************************************************* 函数:对18B20 获取的温度进行处理* *******************************************************/void deal(uintt) {if(flag_dis==1)t=0; if((t<1)||(t>60))beep=0; else beep=1; if(t<10)sw=0;else sw=1; if(t>30)jw=0;else jw=1; } /****************************************************** 函数功能:显示模块* *******************************************************/ void display(uchar temp1,uchar temp2 ) { uchari; lcd_writecom(0x80); delay(3); for(i=0;i<3;i++) {lcd_writedate(table2
); delay(3);} if(flag_dis)lcd_writedate('-'); //结果为负数显示 lcd_writedate(table1[temp1/100]); // 百位为0不显示 delay(3);lcd_writedate(table1[temp1%100/10]); delay(3); lcd_writedate(table1[temp1%100%10]); delay(3); lcd_writedate('.'); //小数点 delay(3); lcd_writedate(table1[temp2]); //lcd_writecom(0x88); lcd_writedate('C'); } voiderror_ds(flag) { uchar i; if(flag==1) {lcd_writecom(0x80); //等待的显示 delay(3); for(i=0;i<16;i++) { lcd_writedate(table); delay(3); } } } /****************************************************** 函数名称:main(void); * *******************************************************/ void main(void) { init_1602(); //LCD 初始化 error_ds(flag); while(init_DS18B20()); //18b20初始化 lcd_writecom(0x01); //清屏 while(1) { tempchange_get(); //温度转换 deal(temp1); //温度处理 display(temp1,temp2); // delay(10); //扫描周期 } }
一周热门 更多>