Computer Science,  STC51

通用型温度报警器

单片机电子设计

2019年12月6日

一.概要:

此实验是以单片机(STC89C52)为核心,结合独立按键和矩阵键盘和DS18B20以及DS1302实现人为输入温度范围,温度阶梯式报警,并记录报警次数及报警对应时间的程序。通过独立按键K1,K2分别控制显示摄氏温度和华氏温度,按键K3按下进入查询与设置温度阈值操作,在此模式下按K5设置温度最低值,按下K6设置温度最高值,再按下K4设置完成并退出此模式。温度阶梯式报警采用5度为一个阶梯,总共20度范围,报警逐渐急促,直至长响。在正常模式下,按住K5查询报警次数。按住K6查询最近一次报警时间,并通过按键复用同时按下键盘查询对应报警的时间,支持存储5组报警数据。

二.编程思想:

DS18B20:温度传感器,通过利用定时器的计数方式提供脉冲,输出得到的温度数据,并保存。

DS1302:万年历程序,利用内部时钟程序,当调用时输出当时时分秒数据。

显示模式摄氏度华氏度:默认为摄氏度显示,调用DS18B20得到温度数据,由按键K1控制,当按键K2按下,调用S18B20得到温度数据,并处理成为华氏温度,当K1按下返回摄氏度显示。

阈值查询设置模式:K3,K4设置为计数器一步溢出模式,当按下K3时进入此模式,可以在数码管看到当前阈值,此时检测P1.6、P1.7电平,当K5、K6按下时分别由键盘输入对应最低最高温度。按下K4即退出此模式。

查询历史报警记录:在显示模式下检测P1.6、P1.7电平,按住K5查询历史报警次数,按住K6查询最近一次报警时间,同时再按下键盘则可查询对应键值的报警时间。

三.原理图:

电路原理图

四.流程框图:

五.核心代码:

通用数组:
unsigned char Data[8];//显示温度数据的8位数组
unsigned char lt[4],ht[4];保存设置最低温度和最高温度的4位数组
code Led[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};
//0-9和‘-’的数码管显示16进制数
code wei[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//数码管的选通码
code key_buf[]={0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,
    0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77};//0-f的键盘扫描码
基础键盘扫描:
char getkey()
{
char key_scan[]={0xef,0xdf,0xbf,0x7f};
char i=0,j=0;
for(i=0;i<4;i++)
{
P2=key_scan[i];
if((P2&0x0f)!=0x0f)
{
for(j=0;j<16;j++)
{
if(key_buf[j]==P2)
return j;
}}}
return -1;}
扫描P2口,如果键值按下则返回键值,无则返回-1;
温度读取:
   unsigned char Chushihua()
{
	unsigned char i;
	IO= 0;		
	i = 70;	
	while(i--);      
	IO = 1;		
	i = 0;
	while(IO)	 
	{ 
		Delay();
		i++;
		if(i>5)      
		{
			return 0;
		}
	}
	return 1;
}

void WriteByte(unsigned char dat)
{
	unsigned int i,j;
	for(j=0; j<8; j++)
	{
		IO= 0;	     	  
		i++;               
		IO= dat & 0x01;  
		i=6;
		while(i--);
		IO= 1;	
		dat >>= 1;
	}
}
unsigned char ReadByte()
{
	unsigned char byte, bi;
	unsigned int i, j;	
	for(j=8; j>0; j--)
	{
	    IO = 0;     
		i++;
		IO = 1;    
		 i++;
		i++;            
		bi = IO;
		byte = (byte >> 1) | (bi << 7);				  
		i = 4;	
		while(i--);
	}				
	return byte;
}
void  ChangTemp()
{
	Chushihua();
	Delay();
	WriteByte(0xcc);		 
	WriteByte(0x44);	   
}
void  ReadTempCom()
{	
    Chushihua();
	Delay();
	WriteByte(0xcc);	
	WriteByte(0xbe);	 
}
int ReadTemp()
{
	int temp = 0;
	unsigned char tmh, tml;
	ChangTemp();			 	
	ReadTempCom();			
	tml = ReadByte();	
	tmh = ReadByte();	
	temp = tmh;
	temp <<= 8;
	temp |= tml;
	return temp;
}
int GetT(int temp)	 
{
   	float tp;  
	if(temp< 0)				
  	{
	    Data[0] = 0x40;
		temp=temp-1;
		temp=~temp;
		tp=temp;
		temp=tp*0.0625*100+0.5; 
  	}
 	else
  	{			
		Data[0] = 0x00;
		tp=temp;
		temp=tp*0.0625*100+0.5;	
	}
	return temp;
}
返回的temp则是温度原始数据,单位为0.01摄氏度
  时间读取:
void Ds1302Write(unsigned char addr, unsigned char dat)
{
    unsigned char n;
    RST = 0;
    _nop_();

    SCLK = 0; 
    _nop_();
    RST = 1;
    _nop_();

    for (n=0; n<8; n++) 
    {
        DSIO = addr & 0x01; 
        addr >>= 1;
        SCLK = 1; 
        _nop_();
        SCLK = 0;
        _nop_();
    }
    for (n=0; n<8; n++) 
    {
        DSIO = dat & 0x01;
        dat >>= 1;
        SCLK = 1; 
        _nop_();
        SCLK = 0;
        _nop_();    
    }   
         
    RST = 0; 
    _nop_();
}

unsigned char Ds1302Read(unsigned char addr)
{
    unsigned char n,dat,dat1;
    RST = 0;
    _nop_();

    SCLK = 0; 
    _nop_();
    RST = 1; 
    _nop_();

    for(n=0; n<8; n++) 
    {
        DSIO = addr & 0x01; 
        addr >>= 1;
        SCLK = 1; 
        _nop_();
        SCLK = 0;//DS1302 
        _nop_();
    }
    _nop_();
    for(n=0; n<8; n++) 
    {
        dat1 = DSIO; 
        dat = (dat>>1) | (dat1<<7);
        SCLK = 1;
        _nop_();
        SCLK = 0;//DS1302 
        _nop_();
    }

    RST = 0;
    _nop_();  
    SCLK = 1;
    _nop_();
    DSIO = 0;
    _nop_();
    DSIO = 1;
    _nop_();
    return dat; 
}

 void Ds1302Init()
{
    unsigned char n;
Ds1302Write(0x8E,0X00);      
    for (n=0; n<7; n++)
    {
        Ds1302Write(WRITE_RTC_ADDR[n],TIME[T][n]); 
    }
    Ds1302Write(0x8E,0x80);     
}

void Ds1302ReadTime()
{
    unsigned char n;
    for (n=0; n<7; n++)年
    {
        TIME[T][n] = Ds1302Read(READ_RTC_ADDR[n]);
    }
        
}
读取温度数据并放入二位数组TIME中第一个参数为第几次,后面存储时分秒。
  阈值查询设置:
       while(1)
	 {
	 if(set==0)
	 {
	  maxt=temh*100;
	  mint=teml*100;
	  break;
	  }
	  k=key;
	  key=getkey();
	   if(statusl==0) {inl=1;inh=0;ic=1;teml=0;}
	  if(statush==0)  {inh=1;inl=0;ic=1;temh=0;}
	  if(inl==1&&key!=-1&&ic<=3&&key<11&&key!=k)
	  {
		lt[ic]=Led[key];
		teml=teml*10+key;
		ic++;
	  }
	  if(inh==1&&key!=-1&&ic<=3&&key<11&&key!=k)
	  {
		ht[ic]=Led[key];
		temh=temh*10+key;
		ic++;
	  }	 
	  displayset();

	 }
按下K5进入最低温度设置程序,标志位inl,通过键盘输入并直接显示,按下K6进入最高温度设置模式,标志位inh,通过键盘输入直接显示。
温度阶梯报警:
if(wendu<=mint||wendu>=maxt)
	 {
	 	updown=1;
	 		if((mint-wendu<=500&&mint-wendu>=0)||(wendu-maxt<=500&&wendu-maxt>=0))
			{
			  for(y=0;y<40;y++)
			  {
			  if(y<20)
			  {
			  	p1_4=1;
				wendu=GetT(ReadTemp()); 
	            dealdata(wendu);
				if(!((mint-wendu<=500&&mint-wendu>=0)||(wendu-maxt<=500&&wendu-maxt>=0))) break;
				display();
				}
			else
			{
			wendu=GetT(ReadTemp()); 
	        dealdata(wendu);
			if(!((mint-wendu<=500&&mint-wendu>=0)||(wendu-maxt<=500&&wendu-maxt>=0))) break;
				p1_4=0;
			   display();
			   }
			}
			}
	 		else if((mint-wendu<=1000&&mint-wendu>=0)||(wendu-maxt<=1000&&wendu-maxt>=0))
			{
			for(y=0;y<20;y++)
			  {
			  if(y<10)
			  {
			  	p1_4=1;
				wendu=GetT(ReadTemp()); 
	            dealdata(wendu);
			if(!((mint-wendu<=1000&&mint-wendu>=0)||(wendu-maxt<=1000&&wendu-maxt>=0))) break;
				display();
				}
			else
			{
			wendu=GetT(ReadTemp()); 
	        dealdata(wendu);
			if(!((mint-wendu<=1000&&mint-wendu>=0)||(wendu-maxt<=1000&&wendu-maxt>=0))) break;
				p1_4=0;
			   display();
			   }
			  }
           }	
            else if((mint-wendu<=1500&&mint-wendu>=0)||(wendu-maxt<=1500&&wendu-maxt>=0))
			{
			for(y=0;y<10;y++)
			  {
			  if(y<5)
			  {
			  	p1_4=1;
				wendu=GetT(ReadTemp()); 
	            dealdata(wendu);
			if(!((mint-wendu<=1500&&mint-wendu>=0)||(wendu-maxt<=1500&&wendu-maxt>=0))) break;
				display();
				}
			else
			{
			wendu=GetT(ReadTemp()); 
	        dealdata(wendu);
			if(!((mint-wendu<=1500&&mint-wendu>=0)||(wendu-maxt<=1500&&wendu-maxt>=0))) break;
				p1_4=0;
			   display();
			   }
			  }
           }
            else if((mint-wendu<=2000&&mint-wendu>=0)||(wendu-maxt<=2000&&wendu-maxt>=0))
			{
			for(y=0;y<4;y++)
			  {
			  if(y<2)
			  {
			  	p1_4=1;
				wendu=GetT(ReadTemp()); 
	            dealdata(wendu);
			if(!((mint-wendu<=2000&&mint-wendu>=0)||(wendu-maxt<=2000&&wendu-maxt>=0))) break;
				display();
				}
			else
			{
			wendu=GetT(ReadTemp()); 
	        dealdata(wendu);
			if(!((mint-wendu<=2000&&mint-wendu>=0)||(wendu-maxt<=2000&&wendu-maxt>=0))) break;
				p1_4=0;
			   display();
			   }
			  }
           }
		   else p1_4=1;
当温度不在设定范围内时,温度报警,温度阶梯式报警采用5度为一个阶梯,总共20度范围,报警逐渐急促,直至长响。

六.源代码:

#include"stdio.h"
#include"reg51.h"
#include"intrins.h"
sbit IO=P1^3;
sbit p1_4=P1^4;
sbit statusl=P1^6;
sbit statush=P1^7;
char tempmod;
bit set=0,updown=0;
bit inl,inh;
int key,ic,k,maxt,mint,temh,teml;
unsigned char Data[8];
unsigned char lt[4],ht[4];
int c,s,y;
code Led[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};
code wei[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
code key_buf[]={0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,
                0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77};
/*---------------------DS18B20----------------------------*/
char num=0;
DisplayData[8];
code READ_RTC_ADDR[] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; 
code WRITE_RTC_ADDR[] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
unsigned char TIME[5][7];
code error[]={0x79,0x31,0x31,0x3f,0x31};//显示错误
code warn[]={0x38,0x3e,0x77,0x31,0x37,0x39,0x09};//显示警告
char T;
sbit DSIO=P1^1;
sbit RST=P1^2;
sbit SCLK=P1^0;
void Ds1302Write(unsigned char addr, unsigned char dat);
unsigned char Ds1302Read(unsigned char addr);
void Ds1302Init();
void Ds1302ReadTime();
/*---------------------DS1302----------------------------*/
void delay1(unsigned int i)
{
    while(i--); 
}
void Ds1302Write(unsigned char addr, unsigned char dat)
{
    unsigned char n;
    RST = 0;
    _nop_();
    SCLK = 0;//先将SCLK置低电平。
    _nop_();
    RST = 1; //然后将RST(CE)置高电平。
    _nop_();
    for (n=0; n<8; n++)//开始传送八位地址命令
    {
        DSIO = addr & 0x01;//数据从低位开始传送
        addr >>= 1;
        SCLK = 1;//数据在上升沿时,DS1302读取数据
        _nop_();
        SCLK = 0;
        _nop_();
    }
    for (n=0; n<8; n++)//写入8位数据
    {
        DSIO = dat & 0x01;
        dat >>= 1;
        SCLK = 1;//数据在上升沿时,DS1302读取数据
        _nop_();
        SCLK = 0;
        _nop_();    
    }          
    RST = 0;//传送数据结束
    _nop_();
}
unsigned char Ds1302Read(unsigned char addr)
{
    unsigned char n,dat,dat1;
    RST = 0;
    _nop_();
    SCLK = 0;//先将SCLK置低电平。
    _nop_();
    RST = 1;//然后将RST(CE)置高电平。
    _nop_();
   for(n=0; n<8; n++)//开始传送八位地址命令
    {
        DSIO = addr & 0x01;//数据从低位开始传送
        addr >>= 1;
        SCLK = 1;//数据在上升沿时,DS1302读取数据
        _nop_();
        SCLK = 0;//DS1302下降沿时,放置数据
        _nop_();
    }
    _nop_();
    for(n=0; n<8; n++)//读取8位数据
    {
        dat1 = DSIO;//从最低位开始接收
        dat = (dat>>1) | (dat1<<7);
        SCLK = 1;
        _nop_();
        SCLK = 0;//DS1302下降沿时,放置数据
        _nop_();
    }
    RST = 0;
    _nop_();    //以下为DS1302复位的稳定时间,必须的。
    SCLK = 1;
    _nop_();
    DSIO = 0;
    _nop_();
    DSIO = 1;
    _nop_();
    return dat; 
}
 void Ds1302Init()
{
    unsigned char n;
    Ds1302Write(0x8E,0X00);      //禁止写保护,就是关闭写保护功能
    for (n=0; n<7; n++)//写入7个字节的时钟信号:分秒时日月周年
    {
        Ds1302Write(WRITE_RTC_ADDR[n],TIME[T][n]); 
    }
    Ds1302Write(0x8E,0x80);      //打开写保护功能
}
void Ds1302ReadTime()
{
    unsigned char n;
    for (n=0; n<7; n++)//读取7个字节的时钟信号:分秒时日月周年
    {
        TIME[T][n] = Ds1302Read(READ_RTC_ADDR[n]);
    }        
}
 void dataset()      
{
    DisplayData[0] = Led[TIME[k][2]/16];               
    DisplayData[1] = Led[TIME[k][2]&0x0f];//存储时              
    DisplayData[2] = 0x40;
    DisplayData[3] = Led[TIME[k][1]/16];               
    DisplayData[4] = Led[TIME[k][1]&0x0f]; //存储分
    DisplayData[5] = 0x40;
    DisplayData[6] = Led[TIME[k][0]/16];               
    DisplayData[7] = Led[TIME[k][0]&0x0f];//存储秒
}
void DataDisplay()
{
int i;
for(i=0;i<8;i++)
{
P2=wei[i];//选通对应位
P0=DisplayData[i];//显示对应位时间数据
delay1(120);
P0=0x00;
delay1(120);//延时刷新防止数据重复
}
}
/*-------萌萌的分割线-----*/
void Delay()
{
	unsigned int x=60;
	for(; x>0; x--);
} 
unsigned char Chushihua()//DS18B20初始化
{
	unsigned char i;
	IO= 0;		  //将总线拉低480us~960us
	i = 70;	//复位
	while(i--);      //延时642us
	IO = 1;		 //然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
	i = 0;
	while(IO)	 //等待DS18B20拉低总线
	{ 
		Delay();
		i++;
		if(i>5)      //等待>5MS
		{
			return 0;//初始化失败
		}
	}
	return 1;//初始化成功
}
void WriteByte(unsigned char dat)//向18B20写入一个字节
{
	unsigned int i,j;
	for(j=0; j<8; j++)
	{
		IO= 0;	     	  //每写入一位数据之前先把总线拉低1us
		i++;               
		IO= dat & 0x01;  //然后写入一个数据,从最低位开始
		i=6;
		while(i--); //延时68us,持续时间最少60us
		IO= 1;	//然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
		dat >>= 1;
	}
}
unsigned char ReadByte()//从18B20读取一个字节
{
	unsigned char byte, bi;
	unsigned int i, j;	
	for(j=8; j>0; j--)
	{
	    IO = 0;     //先将总线拉低1us
		i++;
		IO = 1;     //然后释放总线
		 i++;
		i++;            //延时6us等待数据稳定
		bi = IO;	 //读取数据,从最低位开始读取
		byte = (byte >> 1) | (bi << 7);	//将byte左移一位然后并上右移7位后的bi移动之后移掉那位补0					  
		i = 4;		//读取完之后等待48us再接着读取下一个数
		while(i--);
	}				
	return byte;
}
void  ChangTemp()//让18b20开始转换温度函数
{
	Chushihua();//复位初始化
	Delay();
	WriteByte(0xcc);		//跳过ROM操作命令执行ROM操作,执行后可使用存贮器和控制操作命令		 
	WriteByte(0x44);	    //温度转换命令
}
void  ReadTempCom()//发送读取温度命令
{	
    Chushihua();
	Delay();
	WriteByte(0xcc);	 //跳过ROM操作命令执行ROM操作,执行后可使用存贮器和控制操作命令
	WriteByte(0xbe);	 //发送读取温度命令
}
int ReadTemp()//读取温度
{
	int temp = 0;
	unsigned char tmh, tml;
	ChangTemp();			 	//先写入转换命令
	ReadTempCom();			//然后等待转换完后发送读取温度命令
	tml = ReadByte();		//读取温度值共16位,先读低字节
	tmh = ReadByte();		//再读高字节
	temp = tmh;
	temp <<= 8;
	temp |= tml;
	return temp;
}
int GetT(int temp)	 
{
   	float tp;  
	if(temp< 0)	//当温度值为负数			
  	{
	    Data[0] = 0x40; //   显示负号-
temp=temp-1; //因为读取的温度是实际温度的补码,所以减           1再取反求出原码
		temp=~temp;
		tp=temp;
		temp=tp*0.0625*100+0.5; //高7位是符号位,低四位是小数位 
  	}
 	else
  	{			
		Data[0] = 0x00;
tp=temp; //因为数据处理有小数点所以将温
度赋给一个浮点型变量,正数的原码就是补码它本身
		temp=tp*0.0625*100+0.5;	
	}
	return temp;//返回温度
}
void dealdata(int result)
{  
    if(tempmod==1)//此时为华氏度模式
	{
	result=(result*9)/5+3200;//华氏度转换
	Data[6]=0x63;
    Data[7]=0x71;//华氏度符号
	}
	Else//摄氏度模式
	{
	Data[6]=0x63;
    Data[7]=0x39;//摄氏度符号
	}    
    Data[1]=Led[result/10000];//温度数据百位
	Data[2]=Led[result%10000/1000]; //温度数据十位
	Data[3]=Led[result%1000/100]|0x80; //温度数据个位加小数点
	Data[4]=Led[result%100/10]; //温度数据十分位
	Data[5]=Led[result%10]; //温度数据百分位
}	
void display()//显示温度函数
{
	unsigned char i;
	for(i=0;i<=7;i++)
	{
		P2=wei[i];//选通显示位
		P0=Data[i]; //显示数据
		for( c=0;c<120;c++); 显示刷新延时       	     
	}		}
void displayset()//设置显示函数
{
	unsigned char i=0;
	for(;i<4;i++)//最低温度设置
	{
		P2=wei[i];//选通位
		P0=lt[i]; //输入数据显示
		for( c=0;c<120;c++); //显示刷新延时      	     
	}
	for(;i<7;i++)//最高温度设置
	{
		P2=wei[i]; //选通位
		P0=ht[i-4]; //输入数据显示
		for( c=0;c<120;c++); //显示刷新延时       	     
	}}	
int getkey()
{
char key_scan[]={0xef,0xdf,0xbf,0x7f};
char i=0,j=0;
for(i=0;i<4;i++)
{
P2=key_scan[i];//送入列扫描码
if((P2&0x0f)!=0x0f)
{
for(j=0;j<16;j++)
{
if(key_buf[j]==P2)//查询对应按下按键
return j;//返回按键
}}}
return -1;}//没有按键就返回-1
void sheshidu() interrupt 0//外部中断0,K1控制
{
tempmod=0;切换至摄氏度模式。
}
void startin() interrupt 1//定时器T0一步溢出计数方式
{
 set=1;//设阈值查询设置标志位为1
 inl=0;
 inh=0; //最高最低标志位清除
}
void endin() interrupt 3
{
inl=0; 
inh=0; //最高最低标志位清除
set=0; //设阈值查询设置标志位为0
}
void f() interrupt 2//外部中断1,K2控制
{
tempmod=1;切换至华氏度模式
}
void main()
{ 
int wendu;//温度数据
 Ds1302Init();//DS1302初始化
 T=0;//报警次数初始化
 updown=0;//此标志量用以表示报警的周期完整,只有此标志量实现从0到1再到0的变化,报警次数T才加一。
 k=-1;//此标志量用以消除简直抖动
    maxt=16000;
	mint=-10000;//初始化最大最小阈值
	temh=16000;
teml=-10000; //初始化最大最小阈值
    tempmod=0;初始为显示模式
	p1_4=0;蜂鸣器初始化关闭
	lt[0]=0x38;
	ht[0]=0x76;//阈值查询输入模式的显示文本
	EA=1;
	EX0=1;
	ET0=1;
	ET1=1;
	EX1=1;//开所有中断
	TCON=0x00;
	TMOD=0xee;//T0T1全为计数器一步溢出方式
	TH0=0xff;
	TH1=0xff;
	TL1=0xff;
	TL0=0xff;//一步溢出初值写入
	TR0=1;
	TR1=1;//启动计数器
	s=0;//循环变量初始
	while(1)
	{
	if(set==0)//正常显示模式
	{
	if(statusl==0) //当K5按下查询报警次数
	{
	P2=wei[s];//位选通
	P0=warn[s];//数据写入
	delay1(240);//显示文本“WARNC=”
	P2=wei[7];
	P0=Led[T];
	delay1(60);//显示报警次数T
	s++;
	if(s==7) s=0;//循环标志s循环变化
	}
	else if(statush==0)//当K6按下,查询任意报警时间
	{
	key=getkey();//读取查询的键值
		if(key!=-1)
		{ 
		 k=key;
		}//保存查询的键值
		if(k<5)
		{
		dataset();//处理第k次数据
		DataDisplay();//显示第k次报警的时间
		}
		else//查询超过范围显示“error”
		{
		 for(y=1;y<6;y++)
		 {
		 P2=wei[y];
		 P0=error[y-1];
		 delay1(240);
		 }
		}
	}
	Else//K5K6都没有按下时进行正常工作
	{
	wendu=GetT(ReadTemp()); 
	dealdata(wendu);   	
		display();//读取实时温度并显示
	}
	 if(wendu<=mint||wendu>=maxt)//温度不在设定范围时执行以下
	 {
	 	updown=1;//报警次数标志量置1
	 		if((mint-wendu<=500&&mint-wendu>=0)||(wendu-maxt<=500&&wendu-maxt>=0))//温度偏离阈值5度报警急促度
			{
			  for(y=0;y<40;y++)
			  {
			  if(y<20)
			  {
			  	p1_4=1;
				wendu=GetT(ReadTemp()); 
	            dealdata(wendu);//不停读取实时温度
				if(!((mint-wendu<=500&&mint-wendu>=0)||(wendu-maxt<=500&&wendu-maxt>=0))) break;//报警过程中温度回归正常
则直接跳出报警程序,下同
				display();//显示
				}
			else
			{
			wendu=GetT(ReadTemp()); 
	        dealdata(wendu); //不停读取实时温度
			if(!((mint-wendu<=500&&mint-wendu>=0)||(wendu-maxt<=500&&wendu-maxt>=0))) break;
				p1_4=0;
			   display();提供切换间隔防止报警混乱,下同
			   }}}
	 		else if((mint-wendu<=1000&&mint-wendu>=0)||(wendu-maxt<=1000&&wendu-maxt>=0)) //温度偏离阈值10度报警急促度
			{
			for(y=0;y<20;y++)
			  {
			  if(y<10)
			  {
			  	p1_4=1;
				wendu=GetT(ReadTemp()); 
	            dealdata(wendu);//不停读取实时温度
			if(!((mint-wendu<=1000&&mint-wendu>=0)||(wendu-maxt<=1000&&wendu-maxt>=0))) break;
				display();
				}
			else
			{
			wendu=GetT(ReadTemp()); 
	        dealdata(wendu); //不停读取实时温度
			if(!((mint-wendu<=1000&&mint-wendu>=0)||(wendu-maxt<=1000&&wendu-maxt>=0))) break;
				p1_4=0;
			   display();
		 }  }}	
  else if((mint-wendu<=1500&&mint-wendu>=0)||(wendu-maxt<=1500&&wendu-maxt>=0)) //温度偏离阈值15度报警急促度
			{
			for(y=0;y<10;y++)
			  {
			  if(y<5)
			  {
			  	p1_4=1;
				wendu=GetT(ReadTemp()); 
	            dealdata(wendu); //不停读取实时温度
			if(!((mint-wendu<=1500&&mint-wendu>=0)||(wendu-maxt<=1500&&wendu-maxt>=0))) break;
				display();
				}
			else
			{
			wendu=GetT(ReadTemp()); 
	        dealdata(wendu); //不停读取实时温度
			if(!((mint-wendu<=1500&&mint-wendu>=0)||(wendu-maxt<=1500&&wendu-maxt>=0))) break;
				p1_4=0;
			   display();
			   }  }  }
 else if((mint-wendu<=2000&&mint-wendu>=0)||(wendu-maxt<=2000&&wendu-maxt>=0)) //温度偏离阈值20度报警急促度
			{
			for(y=0;y<4;y++)
			  {
			  if(y<2)
			  {
			  	p1_4=1;
				wendu=GetT(ReadTemp()); 
	            dealdata(wendu);//不停读取实时温度
			if(!((mint-wendu<=2000&&mint-wendu>=0)||(wendu-maxt<=2000&&wendu-maxt>=0))) break;
				display();
				}
			else
			{
			wendu=GetT(ReadTemp()); 
	        dealdata(wendu); //不停读取实时温度
			if(!((mint-wendu<=2000&&mint-wendu>=0)||(wendu-maxt<=2000&&wendu-maxt>=0))) break;
				p1_4=0;
			   display();
			   } }  }
		   else p1_4=1;//温度偏离阈值超过20度

	}
	Else//温度正常
	{
		 p1_4=0;//关闭蜂鸣器
		 if(T<5&&updown==1){//判断是否出现报警
	 	 Ds1302ReadTime();//读取报警时间
		 T++;//报警次数加1
		 updown=0;}//报警标志量初始
	}	}
	else
	{
	 while(1)
	 {
	 if(set==0)//当set==0即关闭设置查询模式
	 {
	  maxt=temh*100;
	  mint=teml*100;//保存设置的温度阈值
	  break;//推出设置查询模式
	  }
	  k=key;//保存当前key值
	  key=getkey();//再读取当前按下键值
 if(statusl==0) {inl=1;inh=0;ic=1;teml=0;}//当K5按下时,最低温度       输入标志量inl置1,允许输入最低温度
if(statush==0)  {inh=1;inl=0;ic=1;temh=0;}//当K6按下时,最高  
         温度输入标志量inh置1,允许输入最高温度
	  if(inl==1&&key!=-1&&ic<=3&&key<11&&key!=k)//最低温度输入 
模式,ic为温度位数,key为温
度值0-9和负号‘-’共十一个, 
且前后键值不能相同,防止键值
抖动出现按一下出现多次输入的
情况。下同
	  {
		lt[ic]=Led[key];
		teml=teml*10+key;
		ic++;//输入温度值且实时处理数据
	  }
	  if(inh==1&&key!=-1&&ic<=3&&key<11&&key!=k)//最高温度输入
	  {
		ht[ic]=Led[key];
		temh=temh*10+key;
		ic++;//输入温度值且实时处理数据
	  }	 
	  displayset();显示实时输入
	 }	}	                		}		}

留言

您的邮箱地址不会被公开。 必填项已用 * 标注