通用型温度报警器
单片机电子设计
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();显示实时输入
} } } }