/*********************************************************//*程序名称:温度监控系统*//*程序功能:利用89C52单片机和DS18B20温度传感器实现环境*//*温度的实时测量和高、低温报警*//*程序版本:v1.0*//*作者:*//*编写时间:*//*********************************************************/#includereg52.h#includeintrins.h//含_nop_()延时函数//定义数据类型#defineucharunsignedchar#defineuintunsignedint//定义端口#defineLEDP0//段码输出口sbitDQ=P3^2;//传感器数据口sbitSMG_q=P1^0;//定义数码管阳级控制脚(千位)sbitSMG_b=P1^1;//定义数码管阳级控制脚(百位)sbitSMG_s=P1^2;//定义数码管阳级控制脚(十位)sbitSMG_g=P1^3;//定义数码管阳级控制脚(个位)sbitbuzzer=P1^5;//蜂鸣器sbitled_low=P2^6;//低温指示灯sbitled_high=P2^7;//高温指示灯sbitled_ok=P2^5;//温度正常指示灯sbitled_work=P2^4;//工作指示灯sbitset=P3^7;//设置按键sbitadd=P3^4;//加一按键sbitdec=P3^5;//减一按键//定义变量和常量intcount=0;//按键次数寄存器inth;//主函数用循环计数器uinttemp;//温度值ucharr;//温度值整数形式ucharhigh=35,low=20;//上下限初值//共阳LED段码表0123456789不亮-ucharcodeLED_code[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};ucharcodeLED_code1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};ucharcodeditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};//小数部分转换码表uchardatatemp_data[2]={0x00,0x00};//存储从传感器读出的温度值uchardatadp[5]={0x00,0x00,0x00,0x00,0x00};//显示单元数据,共4个数据和一个运算//子函数声明voidds_reset();//DS18B20初始化函数voidds_write(uchards_wrdata);//DS18B20写数据函数uchards_read();//DS18B20读数据函数read_temp();//读取温度函数voidchange_temp(uinttem);//温度数据处理voidxianshi(inthorl);//温度显示转换voiddisplay();//数码管显示函数voidkeyscan();//按键查询函数voidwarn_led();//超限报警voiddelay(uintt);//延时函数,单次25us/********************主函数*********************/voidmain(){LED=0x00;//初始化显示端口led1=0;led2=0;led3=0;led4=0;for(h=0;h4;h++){dp[h]=8;}while(1)//循环执行显示和温度读取{uchari;for(i=0;i200;i++){warn_led();//指示灯控制display();//显示keyscan();//按键扫描}change_temp(read_temp());//温度数据读取和处理}}/***********************************************//*函数名称:ds_reset()*//*函数功能:DS18B20初始化*//*入口参数:无*//*输出参数:无*//*调用函数:delay();_nop_();*//*全局变量:无*//*局部变量:presence*//***********************************************/voidds_reset(void){charpresence=1;while(presence){while(presence){DQ=1;//传感器数据段先置高电平_nop_();_nop_();//适当延时DQ=0;//传感器数据段从高电平拉到低电平delay(50);//延时DQ=1;//再置高电平delay(6);//延时presence=DQ;//初始化成功,继续下一步}delay(45);//延时presence=~DQ;}DQ=1;//拉高电平led_work=0;//开工作指示灯}/***********************************************//*函数名称:ds_write()*//*函数功能:向DS18B20写数据*//*入口参数:ds_wrdata*//*输出参数:无*//*调用函数:delay();_nop_();*//*全局变量:无*//*局部变量:ds_wrdata*//***********************************************/voidds_write(uchards_wrdata){uchari;for(i=8;i0;i--){DQ=1;_nop_();_nop_();DQ=0;_nop_();_nop_();_nop_();_nop_();DQ=ds_wrdata&0x01;//最低位移出delay(6);ds_wrdata=ds_wrdata/2;//右移1位}DQ=1;delay(1);}/***********************************************//*函数名称:ds_read()*//*函数功能:从DS18B20读数据*//*入口参数:无*//*输出参数:value*//*调用函数:delay();_nop_();*//*全局变量:*//*局部变量:i;value;*//***********************************************/uchards_read(void){uchari;ucharvalue=0;for(i=8;i0;i--){DQ=1;_nop_();_nop_();value=1;DQ=0;_nop_();_nop_();_nop_();_nop_();DQ=1;_nop_();_nop_();_nop_();_nop_();if(DQ)value|=0x80;delay(6);}DQ=1;return(value);}/***********************************************//*函数名称:read_temp()*//*函数功能:读温度数据数据*//*入口参数:无*//*输出参数:yemp*//*调用函数:ds_reset();ds_write();ds_read();*//*delay();*//*全局变量:temp*//*局部变量:temp_data[];*//***********************************************/read_temp(){ds_reset();//传感器初始化delay(200);ds_write(0xcc);//发跳过读取序列号命令ds_write(0x44);//发温度转换命令ds_reset();delay(1);ds_write(0xcc);ds_write(0xbe);//读18B20中存储器temp_data[0]=ds_read();//读温度值的低字节命令temp_data[1]=ds_read();//读温度值的高字节temp=temp_data[1];temp=8;temp=temp|temp_data[0];//两字节合成一个整型变量returntemp;//返回温度值}/***********************************************//*函数名称:chang_temp()*//*函数功能:将温度传感器中独到的数据进行转换*//*入口参数:tem*//*输出参数:dp[]*//*调用函数:无*//*全局变量:dp[];ditab[];r;*//*局部变量:tem*//***********************************************/voidchange_temp(uinttem){ucharn=0;if(tem6348)//温度值正负判断{tem=65536-tem;//负温度求补码n=1;//标志位置1}dp[4]=tem&0x0f;//取小数部分的值dp[0]=ditab[dp[4]];//存入小数部分显示值dp[4]=tem4;//取中间八位,即整数部分的值dp[3]=dp[4]/100;//取百位数据dp[1]=dp[4]%100;//取后两位数据dp[2]=dp[1]/10;//取十位数据dp[1]=dp[1]%10;//个位r=dp[1]+dp[2]*10+dp[3]*100;//实际温度值(十进制)if(!dp[3])//符号位显示判断{dp[3]=0x0a;//最高位为0时不显示if(!dp[2]){dp[2]=0x0a;//次高位为0时不显示}}if(n){dp[3]=0x0b;//负温度时最高位显示-}}/***********************************************//*函数名称:xianshi()*//*函数功能:温度数据转换成显示所需LED段码*//*入口参数:horl*//*输出参数:dp[]*//*调用函数:无*//*全局变量:dp[];*//*局部变量:n;*//***********************************************/voidxianshi(inthorl){intn=0;if(horl128)//负数补码转换{horl=256-horl;n=1;}dp[3]=horl/100;dp[3]=dp[3]&0x0f;//百位dp[2]=horl%100/10;//十位dp[1]=horl%10;//个位dp[0]=0;//小数位if(!dp[3])//高位为零不显示{dp[3]=0x0a;if(!dp[2]){dp[2]=0x0a;}}if(n)//负数最高位显示“-”{dp[3]=0x0b;}}/***********************************************//*函数名称:display()*//*函数功能:数码管显示*//*入口参数:无*//*输出参数:无*//*调用函数:delay()*//*全局变量:dp[];LED_code[];LED_code1[];*//*led1;led2;led3;led4;*//*局部变量:j;*//***********************************************/voiddisplay(){intj;for(j=0;j4;j++)//4位LED扫描控制{switch(j){case0:LED=LED_code[dp[0]];led4=1;delay(450);led4=0;break;//小数位case1:LED=LED_code1[dp[1]];led3=