|
设计任务与要求
1、以52系列单片机为控制核心,读取DS18B20的ROM号,通过1-wire总线在一个IO上挂多个DS18B20,通过匹配ROM号读取相应温度传感器的温度值;
2、 通过单片机读取DS1302时间送往LCD12864显示时钟;
3、按键扫描,可在温度显示和时钟显示界面之间切换;
4、可设置是否开启过温报警,及单独设置每个温度点的上限温度报警值;
5、当某点温度超过设置温度时,液晶显示温度超过的温度采集点,并通过无线报警,使蜂鸣器鸣叫。
读ROM程序如下:
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit DQ=P1^2;
uchar data RomCode[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
uchar code num[]="0123456789";
/*****************************************************************************/
sbit LCD_cs = P3^5;
sbit LCD_std = P3^6;
sbit LCD_sclk = P3^4;
sbit LCD_psb = P3^7; //H=并口; L=串口;
sbit LCD_rst = P2^7; //Reset Signal 低电平有效
/****************************************************************************/
//函数声明
void Delay(int num);
void LCD_WriteString(unsigned char *str) ; //写字符 例:LCD_WriteString("您好!");
void LCD_WriteDatOrCom(bit ,unsigned char ); //(0,指令) (1,数据)
void LCD_w_byte(unsigned char bbyte); //写一个字节给LCD
void delaynms(unsigned int di); //延时
void LCD_init(void); //LCD初始化
void LCD_clr(void); //清屏
/******************************************************************************/
void Delay(int num)//延时函数
{
while(num--);
}
/****************************************************************************/
void delay_ms(uint x)
{
uint i,j;
for(i=0;i<x;i++)
for(j=0;j<120;j++);
}
//初始化LCD
void LCD_init(void)
{
LCD_rst=1;
LCD_psb=0;
LCD_WriteDatOrCom (0,0x30); /*30---基本指令动作*/
LCD_WriteDatOrCom (0,0x01); /*清屏,地址指针指向00H*/
Delay (100);
LCD_WriteDatOrCom (0,0x06); /*光标的移动方向*/
LCD_WriteDatOrCom(0,0x0c); /*开显示,关游标*/
}
/******************************************************************************/
//写指令或数据 (0,指令) (1,数据)
void LCD_WriteDatOrCom(bit dat_comm,uchar content)
{
uchar a,i,j;
Delay(200);
a=content;
LCD_cs=1;
LCD_sclk=0;
LCD_std=1;
for(i=0;i<5;i++)
{
LCD_sclk=1;
LCD_sclk=0;
}
LCD_std=0;
LCD_sclk=1;
LCD_sclk=0;
if(dat_comm)
LCD_std=1; //data
else
LCD_std=0; //command
LCD_sclk=1;
LCD_sclk=0;
LCD_std=0;
LCD_sclk=1;
LCD_sclk=0;
for(j=0;j<2;j++)
{
for(i=0;i<4;i++)
{
a=a<<1;
LCD_std=CY;
LCD_sclk=1;
LCD_sclk=0;
}
LCD_std=0;
for(i=0;i<4;i++)
{
LCD_sclk=1;
LCD_sclk=0;
}
}
}
/*********************************************************************************/
/*void chn_disp (uchar code *chn)
{
uchar i,j;
LCD_WriteDatOrCom (0,0x30);
LCD_WriteDatOrCom (0,0x80);
for (j=0;j<4;j++)
{
for (i=0;i<16;i++)
LCD_WriteDatOrCom (1,chn[j*16+i]);
}
}
*/
/*****************************************************************************/
//清屏函数
void LCD_clr(void)
{
LCD_WriteDatOrCom (0,0x30);
LCD_WriteDatOrCom (0,0x01);
Delay (100);
}
/*****************************************************************************/
//向LCD发送一个字符串,长度64字符之内。
//应用:LCD_WriteString("您好!");
void LCD_WriteString(unsigned char *str)
{
while(*str != '\0')
{
LCD_WriteDatOrCom(1,*str++);
}
*str = 0;
}
void delay_18B20(uint i)
{
while(i--);
}
void Init_DS18B20(void)
{
uchar x=0;
DQ=1; //DQ复位
delay_18B20(8);
DQ=0;
delay_18B20(80);
DQ=1;
delay_18B20(14);
x=DQ; //稍作延时后如果x=0则初始化成功 x=1则初始化失败
delay_18B20(20);
}
uchar ReadOneChar(void)
{
uchar i=0;
uchar dat=0;
for(i=8;i>0;i--)
{
DQ=0;//给脉冲信号
dat>>=1;
DQ=1;//给脉冲信号
if(DQ)
dat|=0x80;
delay_18B20(4);
}
return(dat);
}
void WriteOneChar(uchar dat)
{
uchar i=0;
for(i=8;i>0;i--)
{
DQ=0;
DQ=dat&0x01;
delay_18B20(5);
DQ=1;
dat>>=1;
}
}
/*void Set_DS18B20()
{
}*/
void Read_RomCord(void)
{
uchar j;
Init_DS18B20();
WriteOneChar(0x33);
for(j=0;j<8;j++)
{
RomCode[j]=ReadOneChar();
}
}
/*
uchar CRC8()
{
uchar i,x;
uchar crcbuff;
crc=0;
for(x=0;x<8;x++)
{
crcbuff=RomCode[x];
for(i=0;i<8;i++)
{
if(((crc^crcbuff)&0x01)==0)
crc>>=1;
else
{
crc^=0x18; //CRC=X8+X5+X4+1
crc>>=1;
crc|=0x80;
}
crcbuff>>=1
}
}
return crc;
} */
void main()
{ uint i;
LCD_init();
LCD_WriteDatOrCom (0,0x80);
LCD_WriteString("丁孟飞,℃梦飞,梦航,梦扬,蓝玻璃");
delay_ms(500);delay_ms(500);delay_ms(500);
delay_ms(500);delay_ms(500);delay_ms(500);
delay_ms(500);delay_ms(500);delay_ms(500);
LCD_clr();
Init_DS18B20();
Read_RomCord();
while(1)
{
LCD_WriteDatOrCom (0,0x80);
for(i=0;i<8;i++)
{
LCD_WriteDatOrCom (1,num[RomCode/100]);
LCD_WriteDatOrCom (1,num[RomCode%100/10]);
LCD_WriteDatOrCom (1,num[RomCode%10]);
LCD_WriteString(" ");
}
}
}
测温应用程序如下:六点测温,无限报警,设置没点上限报警温度,显示万年历
#include <reg52.h>
#include <intrins.h>
#include <stdio.h>
#define uint unsigned int
#define uchar unsigned char
uchar data RomCode[6][8]={{0x28,0x1A,0xA7,0x14,0x02,0x00,0x00,0x91}, //ROM 1
{0x28,0xCC,0x9D,0x14,0x02,0x00,0x00,0xDE}, //ROM 2
{0x28,0xBD,0x70,0x14,0x02,0x00,0x00,0x47}, //ROM 3
{0x28,0xC0,0x8A,0x14,0x02,0x00,0x00,0x8E}, //ROM 4
{0x28,0x90,0x69,0xAF,0x01,0x00,0x00,0xD5}, //ROM 5
{0x28,0x43,0x8C,0x14,0x02,0x00,0x00,0xA1}}; //ROM 6
uchar num[]="0123456789";
uint temp[6];
bit BJ=0;//是否超温报警
/********************************************************************
****按键位定义
********************************************************************/
sbit s1=P2^2;
sbit s2=P2^3;
sbit s3=P2^4;
#define S1 s1==0
#define S2 s2==0
#define S3 s3==0
/********************************************************************
****函数名称:delay_ms(uint x)
****函数功能:毫秒延时函数
****备注说明:
********************************************************************/
void delay_ms(uint x)
{
uint i,j;
for(j=0;j<x;j++)
for(i=0;i<110;i++);
}
/********************************************************************
*********************************************************************
***************************LCD12864部分******************************
*********************************************************************
********************************************************************/
#define LCD_data P0 //数据口
sbit LCD_RS = P1^5; //寄存器选择输入
sbit LCD_RW = P1^6; //液晶读/写控制
sbit LCD_EN = P1^7; //液晶使能控制
/********************************************************************
****函数名称:LCD_WriteCmd
****函数功能:向LCD12864写入命令
****备注说明:RS=L,RW=L,E=A上升沿,D0-D7=命令
********************************************************************/
void LCD_WriteCmd(uchar cmd)
{
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
LCD_data= cmd;
delay_ms(5);
LCD_EN = 1;
delay_ms(5);
LCD_EN = 0;
}
/********************************************************************
****函数名称:LCD_WriteDat
****函数功能:写显示数据到LCD
****备注说明:RS=H,RW=L,E=上升沿,D0-D7=数据
********************************************************************/
void LCD_WriteDat(uchar dat)
{
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
LCD_data= dat;
delay_ms(5);
LCD_EN = 1;
delay_ms(5);
LCD_EN = 0;
}
/********************************************************************
****函数名称:LCD_WriteString
****函数功能:写字符串到LCD
****备注说明:应用例如 LCD_WriteString("你好,梦航");
********************************************************************/
void LCD_WriteString(uchar *str)
{
while(*str != '\0')
{
LCD_WriteDat(*str++);
delay_ms(1);
}
*str = 0;
}
/********************************************************************
****函数名称:LCD_Init()
****函数功能:LCD初始化
****备注说明:
********************************************************************/
void LCD_Init()
{
LCD_WriteCmd(0x30); //基本指令操作
delay_ms(5);
LCD_WriteCmd(0x0C); //显示开,关光标
delay_ms(5);
LCD_WriteCmd(0x01); //清除LCD的显示内容
delay_ms(5);
}
/********************************************************************
*********************************************************************
***************************DS1302部分********************************
*********************************************************************
*********************************************************************/
sbit DS1302_SCLK= P1^0; //DS1302时钟口P1.0
sbit DS1302_IO = P1^1; //DS1302数据口P1.1
sbit DS1302_RST = P1^2; //DS1302片选口P1.2
uchar Year,Month,Day,Week,Hour,Minute,Second;
/********************************************************************
****函数名称:uchar DS1302_Readuchar()
****函数功能:从DS1302读1字节数据
****备注说明:
********************************************************************/
uchar DS1302_Readuchar()
{
uchar i;
uchar dat = 0;
for (i=0; i<8; i++) //8位计数器
{
DS1302_SCLK = 0; //时钟线拉低
_nop_(); //延时等待
_nop_();
dat >>= 1; //数据右移一位
if (DS1302_IO) dat |= 0x80; //读取数据
DS1302_SCLK = 1; //时钟线拉高
_nop_(); //?óê±μè′y
_nop_();
}
return dat;
}
/********************************************************************
****函数名称:DS1302_Writeuchar(uchar dat)
****函数功能:向DS1302写1字节数据
****备注说明:
********************************************************************/
void DS1302_Writeuchar(uchar dat)
{
char i;
for (i=0; i<8; i++) //8位计数器
{
DS1302_SCLK = 0; //时钟线拉低
_nop_(); //延时等待
_nop_();
dat >>= 1; //移出数据
DS1302_IO = CY; //送出到端口
DS1302_SCLK = 1; //时钟线拉高
_nop_(); //延时等待
_nop_();
}
}
/********************************************************************
****函数名称:DS1302_Read(uchar addr)
****函数功能:读DS1302某地址的的数据
****备注说明:
********************************************************************/
uchar DS1302_Read(uchar addr)
{
uchar dat;
DS1302_RST = 0;
_nop_(); //延时等待
_nop_();
DS1302_SCLK = 0;
_nop_(); //延时等待
_nop_();
DS1302_RST = 1;
_nop_(); //延时等待
_nop_();
DS1302_Writeuchar(addr); //写地址
dat = DS1302_Readuchar(); //读数据
DS1302_SCLK = 1;
DS1302_RST = 0;
return dat;
}
/********************************************************************
****函数名称:DS1302_Write(uchar addr, uchar dat)
****函数功能:往DS1302的某个地址写入数据
****备注说明:
********************************************************************/
void DS1302_Write(uchar addr, uchar dat)
{
DS1302_RST = 0;
_nop_(); //延时等待
_nop_();
DS1302_SCLK = 0;
_nop_(); //延时等待
_nop_();
DS1302_RST = 1;
_nop_(); //延时等待
_nop_();
DS1302_Writeuchar(addr); //写地址
DS1302_Writeuchar(dat); //写数据
DS1302_SCLK = 1;
DS1302_RST = 0;
}
/********************************************************************
****函数名称:DS1302_SetTime()
****函数功能:写入DS1302初始时间
****备注说明:
********************************************************************/
void DS1302_SetTime()
{
DS1302_Write(0x8e, 0x00); //允许写操作
DS1302_Write(0x8c, 0x12);//年
DS1302_Write(0x88, 0x03);//月
DS1302_Write(0x86, 0x29);//日
DS1302_Write(0x8a, 0x04);//周
DS1302_Write(0x84, 0x09);//时
DS1302_Write(0x82, 0x01);//分
DS1302_Write(0x80, 0x40);//秒
DS1302_Write(0x8e, 0x80); //写保护
}
/********************************************************************
****函数名称:LCD_ShowTime()
****函数功能:读取当前时间
****备注说明:
********************************************************************/
void LCD_ShowTime()
{
Year=DS1302_Read(0x8d);
Month=DS1302_Read(0x89);
Day=DS1302_Read(0x87);
Week=DS1302_Read(0x8b);
Hour=DS1302_Read(0x85);
Minute=DS1302_Read(0x83);
Second=DS1302_Read(0x81);
LCD_WriteCmd(0x80);
LCD_WriteString("20");
LCD_WriteDat(Year/16+0x30);
LCD_WriteDat(Year%16+0x30);
LCD_WriteString("年");
LCD_WriteDat(Month/16+0x30);
LCD_WriteDat(Month%16+0x30);
LCD_WriteString("月");
LCD_WriteDat(Day/16+0x30);
LCD_WriteDat(Day%16+0x30);
LCD_WriteString("日 ");
LCD_WriteCmd(0x90);
LCD_WriteDat(Hour/16+0x30);
LCD_WriteDat(Hour%16+0x30);
LCD_WriteString(":");
LCD_WriteDat(Minute/16+0x30);
LCD_WriteDat(Minute%16+0x30);
LCD_WriteString(":");
LCD_WriteDat(Second/16+0x30);
LCD_WriteDat(Second%16+0x30);
LCD_WriteString(" 星期");
switch(Week)
{
case 0x01:
LCD_WriteString("一");break;
case 0x02:
LCD_WriteString("二");break;
case 0x03:
LCD_WriteString("三");break;
case 0x04:
LCD_WriteString("四");break;
case 0x05:
LCD_WriteString("五");break;
case 0x06:
LCD_WriteString("六");break;
case 0x07:
LCD_WriteString("日");break;
}
if(BJ==0)
{
LCD_WriteCmd(0x88);
LCD_WriteString("苦心人,天不负!");
LCD_WriteCmd(0x98);
LCD_WriteString("有志者,事竞成!");
}
if(BJ==1)
{
LCD_WriteCmd(0x88);
LCD_WriteString("超温报警点: ");
}
}
/********************************************************************
*********************************************************************
***************************DS18B20部分*******************************
*********************************************************************
*********************************************************************/
sbit DQ=P1^3;
/********************************************************************
****函数名称:delay_18B20()
****函数功能:DS18B20短延时
****备注说明:
********************************************************************/
void delay_18B20(uint i)
{
while(i--);
}
/********************************************************************
****函数名称:DS18B20_Init()
****函数功能:DS18B20初始化
****备注说明:
********************************************************************/
void DS18B20_Init(void)
{
uchar x=0;
DQ=1; //DQ复位
delay_18B20(8);
DQ=0;
delay_18B20(80);
DQ=1;
delay_18B20(14);
x=DQ; //稍作延时后如果x=0则初始化成功 x=1则初始化失败
delay_18B20(20);
}
/********************************************************************
****函数名称:ReadOneChar(void)
****函数功能:DS18B20读一个字节数据
****备注说明:
********************************************************************/
uchar ReadOneChar(void)
{
uchar i=0;
uchar dat=0;
for(i=8;i>0;i--)
{
DQ=0;//给脉冲信号
dat>>=1;
DQ=1;//给脉冲信号
if(DQ)//如果DQ为1则初始化成功
dat|=0x80;
delay_18B20(4);
}
return(dat);
}
/********************************************************************
****函数名称:WriteOneChar(void)
****函数功能:DS18B20写一个字节数据
****备注说明:
********************************************************************/
void WriteOneChar(uchar dat)
{
uchar i=0;
for(i=8;i>0;i--)
{
DQ=0;
DQ=dat&0x01;
delay_18B20(5);
DQ=1;
dat>>=1;
}
}
/********************************************************************
****函数名称:ReadTemp(uchar x)
****函数功能:读取X通道数据
****备注说明:X范围1-6,温度值放大十倍输出
********************************************************************/
int ReadTemp(uchar x)//读取通道x的温度值
{
uchar i,temp_H,temp_L;
int WEN;
DS18B20_Init();
delay_18B20(80);
WriteOneChar(0xcc);//跳过读ROM号
WriteOneChar(0x44);//所有的传感器开始转换温度
delay_ms(50);
DS18B20_Init();
WriteOneChar(0x55); //发送ROM匹配命令
for(i=0;i<8;i++)
WriteOneChar(RomCode[x-1]);
WriteOneChar(0xBE); //读温度寄存器(共可读9个寄存器)前两个是温度
delay_18B20(80);
temp_L=ReadOneChar(); //读取温度的低位
temp_H=ReadOneChar(); //读取温度的高位
WEN=(int)((temp_H*256+temp_L)*0.625);//温度放大十倍输出
return(WEN);
}
/********************************************************************
****函数名称:LCD_ShowTemp()
****函数功能:向LCD写入温度
****备注说明:
********************************************************************/
void LCD_ShowTemp()
{
temp[0]=ReadTemp(1);
temp[1]=ReadTemp(2);
temp[2]=ReadTemp(3);
temp[3]=ReadTemp(4);
temp[4]=ReadTemp(5);
temp[5]=ReadTemp(6);
LCD_WriteCmd(0x80);
LCD_WriteString("温度检测中………");
LCD_WriteCmd(0x90);
LCD_WriteString("①");
LCD_WriteDat(num[temp[0]/100]);//十位
LCD_WriteDat(num[temp[0]%100/10]);//个位
LCD_WriteString(".");
LCD_WriteDat(num[temp[0]%10]);//十分位
LCD_WriteString("℃");
LCD_WriteString("②");
LCD_WriteDat(num[temp[1]/100]);//十位
LCD_WriteDat(num[temp[1]%100/10]);//个位
LCD_WriteString(".");
LCD_WriteDat(num[temp[1]%10]);//十分位
LCD_WriteString("℃");
LCD_WriteCmd(0x88);
LCD_WriteString("③");
LCD_WriteDat(num[temp[2]/100]);//十位
LCD_WriteDat(num[temp[2]%100/10]);//个位
LCD_WriteString(".");
LCD_WriteDat(num[temp[2]%10]);//十分位
LCD_WriteString("℃");
LCD_WriteString("④");
LCD_WriteDat(num[temp[3]/100]);//十位
LCD_WriteDat(num[temp[3]%100/10]);//个位
LCD_WriteString(".");
LCD_WriteDat(num[temp[3]%10]);//十分位
LCD_WriteString("℃");
LCD_WriteCmd(0x98);
LCD_WriteString("⑤");
LCD_WriteDat(num[temp[4]/100]);//十位
LCD_WriteDat(num[temp[4]%100/10]);//个位
LCD_WriteString(".");
LCD_WriteDat(num[temp[4]%10]);//十分位
LCD_WriteString("℃");
LCD_WriteString("⑥");
LCD_WriteDat(num[temp[5]/100]);//十位
LCD_WriteDat(num[temp[5]%100/10]);//个位
LCD_WriteString(".");
LCD_WriteDat(num[temp[5]%10]);//十分位
LCD_WriteString("℃");
}
/********************************************************************
****函数名称:LCD_ShowWelcome()
****函数功能:向LCD写入开机欢迎界面
****备注说明:按下S1键显示下一页
********************************************************************/
void LCD_ShowWelcome()
{
LCD_WriteCmd(0x80);
LCD_WriteString("基于1-wire总线的");
LCD_WriteString("作者:丁孟飞 ");
LCD_WriteString("多点测温报警系统");
LCD_WriteString("学号:2009041507");
while((s1!=0)&&(s2!=0)&&(s3!=0)); //按下任意键,进入下一页显示
LCD_WriteCmd(0x01);
LCD_WriteCmd(0x80);
LCD_WriteString(" 操作说明 ");
LCD_WriteString("时间,短按S1显示");
LCD_WriteString("1.初始化界面显示");
LCD_WriteString("温度检测界面,再");
while((s1!=0)&&(s2!=0)&&(s3!=0));//按下任意键,进入下一页显示
LCD_WriteCmd(0x01);
LCD_WriteCmd(0x80);
LCD_WriteString("按返回时间界面显");
LCD_WriteString("2.长按S1进入温度");
LCD_WriteString("示,循环之。 ");
LCD_WriteString("报警设置,可以设");
while((s1!=0)&&(s2!=0)&&(s3!=0));//按下任意键,进入下一页显示
LCD_WriteCmd(0x01);
LCD_WriteCmd(0x80);
LCD_WriteString("置是否开启过温报");
LCD_WriteString("点的报警温度。 ");
LCD_WriteString("警功能及设置每个");
LCD_WriteString("在使用过程中有好");
while((s1!=0)&&(s2!=0)&&(s3!=0));//按下任意键,进入下一页显示
LCD_WriteCmd(0x01);
LCD_WriteCmd(0x80);
LCD_WriteString("的建议请不吝赐教");
LCD_WriteString("权归本人所有,再");
LCD_WriteString("。本作品最终解释");
LCD_WriteString("次谢谢使用! ");
while((s1!=0)&&(s2!=0)&&(s3!=0));//按下任意键,进入下一页显示
LCD_WriteCmd(0x01);
LCD_WriteCmd(0x80);
LCD_WriteString(" ");
LCD_WriteString(" ");
LCD_WriteString("请输入开机密码:");
LCD_WriteString(" ");
}
/********************************************************************
****函数名称:KeyScan()
****函数功能:案件处理程序,也是最复杂的啊
****备注说明:开机后显示欢迎界面,按下S1翻页,欢迎界面后显示时钟界面,
短按S1显示六点温度检测界面,再按显示时钟界面,再按循环,
长按S1键进入温度报警设置界面,可设置是否允许过温报警及
设置每一点的高温报警温度。
********************************************************************/
bit chang=0,//长按及短按标志位
TorW=0, //显示温度设定或者始终欢迎界面,0显示失踪接界面,1显示温度检测界面
ENABLE_BJ=0; //是否开启过温报警功能
uint press_num=0;//记录按键S1按下的时间
uint BJT0=350,BJT1=350,BJT2=350,BJT3=350,BJT4=350,BJT5=350,//六个报警温度
s1num=0; //记录按键S1长按再次按下的次数
void KeyScan()
{
/*******************************************************************
*************************按键S1处理程序*****************************
*******************************************************************/
if(S1)
{
delay_ms(20); //z延时消抖动
if(S1)
{
while(S1)
{
press_num++;
delay_ms(20);//20ms延时
if(press_num==150)
break;
}
if(press_num>140) //按下时间大于3秒为长按
{
press_num=0;
chang=1;
LCD_WriteCmd(0x01);//清屏
LCD_WriteCmd(0x80);
LCD_WriteString("是否开启报警:否");//设置是否开启过温报警功能
LCD_WriteCmd(0x90);
LCD_WriteString("①");
LCD_WriteDat(num[BJT0/100]);//十位
LCD_WriteDat(num[BJT0%100/10]);//个位
LCD_WriteString(".");
LCD_WriteDat(num[BJT0%10]);//十分位
LCD_WriteString("℃");
LCD_WriteString("②");
LCD_WriteDat(num[BJT1/100]);//十位
LCD_WriteDat(num[BJT1%100/10]);//个位
LCD_WriteString(".");
LCD_WriteDat(num[BJT1%10]);//十分位
LCD_WriteString("℃");
LCD_WriteCmd(0x88);
LCD_WriteString("③");
LCD_WriteDat(num[BJT2/100]);//十位
LCD_WriteDat(num[BJT2%100/10]);//个位
LCD_WriteString(".");
LCD_WriteDat(num[BJT2%10]);//十分位
LCD_WriteString("℃");
LCD_WriteString("④");
LCD_WriteDat(num[BJT3/100]);//十位
LCD_WriteDat(num[BJT3%100/10]);//个位
LCD_WriteString(".");
LCD_WriteDat(num[BJT3%10]);//十分位
LCD_WriteString("℃");
LCD_WriteCmd(0x98);
LCD_WriteString("⑤");
LCD_WriteDat(num[BJT4/100]);//十位
LCD_WriteDat(num[BJT4%100/10]);//个位
LCD_WriteString(".");
LCD_WriteDat(num[BJT4%10]);//十分位
LCD_WriteString("℃");
LCD_WriteString("⑥");
LCD_WriteDat(num[BJT5/100]);//十位
LCD_WriteDat(num[BJT5%100/10]);//个位
LCD_WriteString(".");
LCD_WriteDat(num[BJT5%10]);//十分位
}
if((press_num<=100)&&(chang==0))//按下时间小于等于2秒为短按
{
press_num=0;
chang=0;
TorW=~TorW;
}
if(press_num<=100&&(chang==1)) //在调整报警温度时短按进入下一项调整
{
s1num++;
switch(s1num)
{ //光标闪烁点定位
case 1: LCD_WriteCmd(0x87);
LCD_WriteCmd(0x0f);
break;
case 2: LCD_WriteCmd(0x90);
break;
case 3: LCD_WriteCmd(0x94);
break;
case 4: LCD_WriteCmd(0x88);
break;
case 5: LCD_WriteCmd(0x8c);
break;
case 6: LCD_WriteCmd(0x98);
break;
case 7: LCD_WriteCmd(0x9c);
break;
case 8: chang=0;
s1num=0;
LCD_WriteCmd(0x0C);//光标不闪烁
LCD_WriteCmd(0x01);//清屏
LCD_ShowTime();//返回时钟显示界面
break;
}
}
}
}
/*******************************************************************
*************************按键S2处理程序*****************************
*******************************************************************/
if(s1num!=0)//只有S1长按下后才检测S2
{
if(S2)
{
delay_ms(20);
if(S2)
{
while(S2);//等待S2松开
switch(s1num)
{
case 1:
ENABLE_BJ=~ENABLE_BJ;
LCD_WriteCmd(0x0C);//光标不闪烁
if(ENABLE_BJ==0)
{
LCD_WriteCmd(0x87);
LCD_WriteString("否");//设置是否开启过温报警功能
}
else
{
LCD_WriteCmd(0x87);
LCD_WriteString("是");//设置是否开启过温报警功能
}
LCD_WriteCmd(0x87);
LCD_WriteCmd(0x0F);
break;
case 2:
BJT0=BJT0+5;
LCD_WriteCmd(0x0C);//光标不闪烁
LCD_WriteCmd(0x91);
LCD_WriteDat(num[BJT0/100]);//十位
LCD_WriteDat(num[BJT0%100/10]);//个位
LCD_WriteString(".");
LCD_WriteDat(num[BJT0%10]);//十分位
LCD_WriteCmd(0x90);
LCD_WriteCmd(0x0F);
break;
case 3:
BJT1=BJT1+5;
LCD_WriteCmd(0x0C);//光标不闪烁
LCD_WriteCmd(0x95);
LCD_WriteDat(num[BJT1/100]);//十位
LCD_WriteDat(num[BJT1%100/10]);//个位
LCD_WriteString(".");
LCD_WriteDat(num[BJT1%10]);//十分位
LCD_WriteCmd(0x94);
LCD_WriteCmd(0x0F);
break;
case 4:
BJT2=BJT2+5;
LCD_WriteCmd(0x89);
LCD_WriteCmd(0x0C);//光标不闪烁
LCD_WriteDat(num[BJT2/100]);//十位
LCD_WriteDat(num[BJT2%100/10]);//个位
LCD_WriteString(".");
LCD_WriteDat(num[BJT2%10]);//十分位
LCD_WriteCmd(0x88);
LCD_WriteCmd(0x0F);
break;
case 5:
BJT3=BJT3+5;
LCD_WriteCmd(0x0C);//光标不闪烁
LCD_WriteCmd(0x8D);
LCD_WriteDat(num[BJT3/100]);//十位
LCD_WriteDat(num[BJT3%100/10]);//个位
LCD_WriteString(".");
LCD_WriteDat(num[BJT3%10]);//十分位
LCD_WriteCmd(0x8C);
LCD_WriteCmd(0x0F);
break;
case 6:
BJT4=BJT4+5;
LCD_WriteCmd(0x0C);//光标不闪烁
LCD_WriteCmd(0x99);
LCD_WriteDat(num[BJT4/100]);//十位
LCD_WriteDat(num[BJT4%100/10]);//个位
LCD_WriteString(".");
LCD_WriteDat(num[BJT4%10]);//十分位
LCD_WriteCmd(0x98);
LCD_WriteCmd(0x0F);
break;
case 7:
BJT5=BJT5+5;
LCD_WriteCmd(0x0C);//光标不闪烁
LCD_WriteCmd(0x9D);
LCD_WriteDat(num[BJT5/100]);//十位
LCD_WriteDat(num[BJT5%100/10]);//个位
LCD_WriteString(".");
LCD_WriteDat(num[BJT5%10]);//十分位
LCD_WriteCmd(0x9C);
LCD_WriteCmd(0x0F);
break;
}
}
}
}
/*******************************************************************
*************************按键S3处理程序*****************************
*******************************************************************/
if(s1num!=0)//只有S1长按下后才检测S3
{
if(S3)
{
delay_ms(20);
if(S3)
{
while(S3);//等待S3松开
switch(s1num)
{
case 1:
ENABLE_BJ=~ENABLE_BJ;
LCD_WriteCmd(0x0C);//光标不闪烁
if(ENABLE_BJ==0)
{
LCD_WriteCmd(0x87);
LCD_WriteString("否");//关闭过温报警功能
}
else
{
LCD_WriteCmd(0x87);
LCD_WriteString("是");//开启过温报警功能
}
LCD_WriteCmd(0x87);
LCD_WriteCmd(0x0F);//光标闪烁
break;
case 2:
BJT0=BJT0-5;
LCD_WriteCmd(0x91);
LCD_WriteCmd(0x0C);//光标不闪烁
LCD_WriteDat(num[BJT0/100]);//十位
LCD_WriteDat(num[BJT0%100/10]);//个位
LCD_WriteString(".");
LCD_WriteDat(num[BJT0%10]);//十分位
LCD_WriteCmd(0x90);
LCD_WriteCmd(0x0F);//光标闪烁
break;
case 3:
BJT1=BJT1-5;
LCD_WriteCmd(0x0C);//光标不闪烁
LCD_WriteCmd(0x95);
LCD_WriteDat(num[BJT1/100]);//十位
LCD_WriteDat(num[BJT1%100/10]);//个位
LCD_WriteString(".");
LCD_WriteDat(num[BJT1%10]);//十分位
LCD_WriteCmd(0x94);
LCD_WriteCmd(0x0F);//光标闪烁
break;
case 4:
BJT2=BJT2-5;
LCD_WriteCmd(0x0C);//光标不闪烁
LCD_WriteCmd(0x89);
LCD_WriteDat(num[BJT2/100]);//十位
LCD_WriteDat(num[BJT2%100/10]);//个位
LCD_WriteString(".");
LCD_WriteDat(num[BJT2%10]);//十分位
LCD_WriteCmd(0x88);
LCD_WriteCmd(0x0F);//光标闪烁
break;
case 5:
BJT3=BJT3-5;
LCD_WriteCmd(0x0C);//光标不闪烁
LCD_WriteCmd(0x8D);
LCD_WriteDat(num[BJT3/100]);//十位
LCD_WriteDat(num[BJT3%100/10]);//个位
LCD_WriteString(".");
LCD_WriteDat(num[BJT3%10]);//十分位
LCD_WriteCmd(0x8C);
LCD_WriteCmd(0x0F);//光标闪烁
break;
case 6:
BJT4=BJT4-5;
LCD_WriteCmd(0x0C);//光标不闪烁
LCD_WriteCmd(0x99);
LCD_WriteDat(num[BJT4/100]);//十位
LCD_WriteDat(num[BJT4%100/10]);//个位
LCD_WriteString(".");
LCD_WriteDat(num[BJT4%10]);//十分位
LCD_WriteCmd(0x98);
LCD_WriteCmd(0x0F);//光标闪烁
break;
case 7:
BJT5=BJT5-5;
LCD_WriteCmd(0x0C);//光标不闪烁
LCD_WriteCmd(0x9D);
LCD_WriteDat(num[BJT5/100]);//十位
LCD_WriteDat(num[BJT5%100/10]);//个位
LCD_WriteString(".");
LCD_WriteDat(num[BJT5%10]);//十分位
LCD_WriteCmd(0x9C);
LCD_WriteCmd(0x0F);//光标闪烁
break;
}
}
}
}
}
/********************************************************************
*********************************************************************
***************************蜂鸣器报警部分****************************
*********************************************************************
*********************************************************************/
sbit set_beep=P3^4;
sbit clr_beep=P3^0;
#define Set_Beep set_beep=0
#define Clr_Beep clr_beep=0
/********************************************************************
****函数名称:baojing()
****函数功能:检测温度,超过设置的上限温度时报警,并液晶显示相应的报警点
****备注说明:
********************************************************************/
void baojing()
{
uint i;
if(BJ==0)
{
Clr_Beep;
}
if(BJ==1) //只有在报警允许情况下才比较温度,超过设定的温度时提示
{
temp[0]=ReadTemp(1);
temp[1]=ReadTemp(2);
temp[2]=ReadTemp(3);
temp[3]=ReadTemp(4);
temp[4]=ReadTemp(5);
temp[5]=ReadTemp(6);
if(temp[0]>=BJT0)//第一点温度超过设置温度
{
if((TorW==0)&&(chang==0))
{
LCD_WriteCmd(0x98);
LCD_WriteString("①");
}
if((TorW==1)&&(chang==0))
{
LCD_WriteCmd(0x0C);
LCD_WriteCmd(0x90);
LCD_WriteCmd(0x0F);
}
for(i=0;i<5;i++)
{
Set_Beep;
delay_ms(200);
Clr_Beep;
delay_ms(200);
}
}
if(temp[1]>=BJT1)//第二点温度超过设置温度
{
if((TorW==0)&&(chang==0))
{
LCD_WriteCmd(0x99);
LCD_WriteString("②");
}
if((TorW==1)&&(chang==0))
{
LCD_WriteCmd(0x94);
LCD_WriteCmd(0x0f);
}
for(i=0;i<5;i++)
{
Set_Beep;
delay_ms(200);
Clr_Beep;
delay_ms(200);
}
}
if(temp[2]>=BJT2)//第三点温度超过设置温度
{
if((TorW==0)&&(chang==0))
{
LCD_WriteCmd(0x9a);
LCD_WriteString("③");
}
if((TorW==1)&&(chang==0))
{
LCD_WriteCmd(0x88);
LCD_WriteCmd(0x0f);
}
for(i=0;i<5;i++)
{
Set_Beep;
delay_ms(200);
Clr_Beep;
delay_ms(200);
}
}
if(temp[3]>=BJT3)//第四点温度超过设置温度
{
if((TorW==0)&&(chang==0))
{
LCD_WriteCmd(0x9b);
LCD_WriteString("④");
}
if((TorW==1)&&(chang==0))
{
LCD_WriteCmd(0x8c);
LCD_WriteCmd(0x0f);
}
for(i=0;i<5;i++)
{
Set_Beep;
delay_ms(200);
Clr_Beep;
delay_ms(200);
}
}
if(temp[4]>=BJT4)//第五点温度超过设置温度
{
if(TorW==0)
{
LCD_WriteCmd(0x9c);
LCD_WriteString("⑤");
}
if(TorW==1)
{
LCD_WriteCmd(0x98);
LCD_WriteCmd(0x0f);
}
for(i=0;i<5;i++)
{
Set_Beep;
delay_ms(200);
Clr_Beep;
delay_ms(200);
}
}
if(temp[5]>=BJT5)//第六点温度超过设置温度
{
if((TorW==0)&&(chang==0))
{
LCD_WriteCmd(0x9d);
LCD_WriteString("⑥");
}
if((TorW==1)&&(chang==0))
{
LCD_WriteCmd(0x9c);
LCD_WriteCmd(0x0f);
}
for(i=0;i<5;i++)
{
Set_Beep;
delay_ms(200);
Clr_Beep;
delay_ms(200);
}
}
}
}
uchar i,m1=0,m2=0,m3=0,m4=0,bijiao=0,s1_count=0;
uchar MM[4]={1,5,0,7};//初始密码
uchar mima[4];//密码存储数组
void main()
{
LCD_Init();
DS18B20_Init();
// DS1302_SetTime();
LCD_ShowWelcome();
while(s1_count!=6)
{
if(S1)
{
delay_ms(30);
if(S1)
{
while(!s1);
s1_count++;
switch(s1_count)
{
case 1:
LCD_WriteCmd(0x88);
LCD_WriteString(" ");
LCD_WriteCmd(0x8A);
LCD_WriteCmd(0x0F);//闪烁
break;
case 2:
LCD_WriteCmd(0x8B);
mima[0]=m1;
break;
case 3:
LCD_WriteCmd(0x8C);
mima[1]=m2;
break;
case 4:
LCD_WriteCmd(0x8D);
mima[2]=m3;
break;
case 5:
LCD_WriteCmd(0x0c);//取消闪烁
mima[3]=m4;
delay_ms(100);
for(i=0;i<4;i++)
{
if(MM==mima)
bijiao++;
}
if(bijiao==4)
{
LCD_WriteCmd(0x0C);
LCD_WriteCmd(0x88);
LCD_WriteString(" 密码正确 ");
delay_ms(1000);
LCD_WriteCmd(0x01);
LCD_WriteCmd(0x90);
LCD_WriteString("系统正在启动……");
LCD_WriteCmd(0x88);
LCD_WriteString("■");
delay_ms(400);
LCD_WriteString("■");
delay_ms(400);
LCD_WriteString("■");
delay_ms(400);
LCD_WriteString("■");
delay_ms(400);
LCD_WriteString("■");
delay_ms(400);
LCD_WriteString("■");
delay_ms(400);
LCD_WriteString("■");
delay_ms(400);
LCD_WriteString("■");
delay_ms(400);
s1_count=6;
}
else
{
LCD_WriteCmd(0x0C);
LCD_WriteCmd(0x88);
LCD_WriteString(" 密码错误 ");
delay_ms(1000);
LCD_WriteCmd(0x90);
LCD_WriteString("请重新输入密码:");
LCD_WriteCmd(0x88);
LCD_WriteString(" ");
/*LCD_WriteCmd(0x8A);
LCD_WriteCmd(0x0F);//闪烁*/
m1=0,m2=0,m3=0,m4=0;
s1_count=0;
bijiao=0;
}
break;
}
}
}
if(S2)
{
delay_ms(50);
if(S2)
{
while(!s2);
switch(s1_count)
{
case 1:m1++;
if(m1==10)
m1=0;
LCD_WriteCmd(0x0C);
LCD_WriteCmd(0x8A);
LCD_WriteDat(num[m1]);
LCD_WriteCmd(0x0F);
LCD_WriteCmd(0x8A);
break;
case 2:m2++;
if(m2==10)
m2=0;
LCD_WriteCmd(0x0C);
LCD_WriteCmd(0x8B);
LCD_WriteDat(num[m2]);
LCD_WriteCmd(0x0F);
LCD_WriteCmd(0x8B);
break;
case 3:m3++;
if(m3==10)
m3=0;
LCD_WriteCmd(0x0C);
LCD_WriteCmd(0x8C);
LCD_WriteDat(num[m3]);
LCD_WriteCmd(0x0F);
LCD_WriteCmd(0x8C);
break;
case 4:m4++;
if(m4==10)
m4=0;
LCD_WriteCmd(0x0C);
LCD_WriteCmd(0x8D);
LCD_WriteDat(num[m4]);
LCD_WriteCmd(0x0F);
LCD_WriteCmd(0x8D);
break;
}
}
}
if(S3)
{
delay_ms(50);
if(S3)
{
while(!s3);
switch(s1_count)
{
case 1:m1--;
if(m1<0)
m1=9;
LCD_WriteCmd(0x0C);
LCD_WriteCmd(0x8A);
LCD_WriteDat(num[m1]);
LCD_WriteCmd(0x0F);
LCD_WriteCmd(0x8A);
break;
case 2:m2--;
if(m2<0)
m2=9;
LCD_WriteCmd(0x0C);
LCD_WriteCmd(0x8B);
LCD_WriteDat(num[m2]);
LCD_WriteCmd(0x0F);
LCD_WriteCmd(0x8B);
break;
case 3:m3--;
if(m3<0)
m3=9;
LCD_WriteCmd(0x0C);
LCD_WriteCmd(0x8C);
LCD_WriteDat(num[m3]);
LCD_WriteCmd(0x0F);
LCD_WriteCmd(0x8C);
break;
case 4:m4--;
if(m4<0)
m4=9;
LCD_WriteCmd(0x0C);
LCD_WriteCmd(0x8D);
LCD_WriteDat(num[m4]);
LCD_WriteCmd(0x0F);
LCD_WriteCmd(0x8D);
break;
}
}
}
}
while(1)
{
if((TorW==0)&&(chang==0))
{
LCD_ShowTime();
}
if((TorW==1)&&(chang==0))
{
LCD_ShowTemp();
}
KeyScan();
baojing();
}
}
资料转载于他站 仅供同学学习
|
|