查看: 1422|回复: 0
打印 上一主题 下一主题

看不少网友说1-wire总线协议多点测温的,贴个自己写成功的

[复制链接]
跳转到指定楼层
沙发
发表于 2016-3-28 16:05:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
设计任务与要求
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();
        }                                       
}




资料转载于他站  仅供同学学习
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入中科因仑

本版积分规则

快速回复 返回顶部 返回列表