基于单片机的智能热水箱设计代码加演示

1 系统总需求  

要求热水箱的额温度控制系统能完成以下功能:具备基础的提示功能、使用液晶显示、温度上下限的设定,时间的开始及结束、手动设定温度、控温范围在0℃—99℃,精度于±1℃以内、具备自动控制加热的功能。

根据以上设计的方案,需要实现下面几点设计的需求:在整体上采用了AT89C52单片机芯片,其他主要模块如DS18b20测温传感器以及LCD1602液晶显示,组成实现温度的实时测量读取并显示。由于是对水温的控制测量的范围就不用再麻烦到人为的去设置而是在程序中进行写死,到时候只需要人为按键设置指定的温度值。经过比对温度的标定值来达到热水器自动控制热加热,并进行报警显示。也可以在启动电源后也可进行加热时长控制,在到达时间后停止加热。

2 总体方案设计  

温度控制系统主要组成是由:防水DS18b20测温传感器模块核心单片机是(AT89C52)模块、DS1302时钟定时模块、独立按键设置及控制模块、液晶LCD1602模块显示,LED红色警示灯模块以及蜂鸣器模块组成可以采用实际电路搭建和Proteus仿真(为了方便调试我这里选择了仿真完成)。

3主要模块电路功能简介

(1)、单片机模块

主要的单片机部分采用52系列,在本次设计中采用AT89C52作为整个设计的控制中心,作用于温度显示、信号传递、系统驱动、报警控制、电机控制等各个模块之间的相互配合,协同工作。相当于整个设计的心脏位置[6]

(2)、温度检测模块

定期循环收集温度信号以确定是否已达到设定温度,并将其发送到单片微处理器进行处理。

(3)、液晶显示模块

用于显示热水箱中实时加热水的温度,便于温度对外观测变化以及对温度的处理。

(4)、控制按键模块

在本次设计中采用五个独立按键连接于MCU,用于对单片机的P1端口进行操作,按键输入控制信号到IO,一可以使用按键设置相应的模式,控制设定标准温度的最大和最小值并用来增加或减少设定值。二可以使用按键控制模式的设定,按下按键时,显示屏上的光标会移动到要设置的位置。时间控制按键来设置时间的开始和停止,按下后可根据设定的时间来加热定长时间的热水。以此来达到控制热水器继电器(模拟加热)的开启或关闭。

(5)、加热装置模块

用于加热水中的水,使水达到设定的温度。

(6)警示灯模块

当水箱中的水人工设置加热温度,达到加热时间和温度指示灯亮开启加热提醒用户。

4 软件设计

在软件开发设计中,整体采用C语言编写,此次软件系统中使用的单片机芯片是AT89C52单片机,这里有两种编程语言供我们选择,分别是系统友好的汇编语言和代码逻辑清晰、可移植性强的C语言,由于汇编常用于编写跟系统硬件有关的程序,在硬件处理解释起来非常方便高效,例如在访问到具体的I/O端口,中断子程序的实时控制,通讯端口的及时访问等要求比较高效的程序模块。而相比较来说,C语言比较适合于逻辑上的运算,方便于向其他程序中移植,降低我们编写代码的时间,提高我们的编程效率。两种语言都是有自己各自的优点,但是我们此次的设计中使用到的逻辑运算比较多,因此选用到C51高级语言编写。

在整体模块中主要可以分为五个逻辑控制部分,分别是(1):独立按键处理部分(2):温度数据处理部分也就是微控制器(3):电机(模拟加热)驱动部分(4):蜂鸣器及LED部分(5):lcd1602显示部分主体的程序流程图如下:

按键部分流程图:

按键部分整体在main函数中的死循环中,其实的主要功能就是用来对温度的设定值进行增减操作,并且循环检测按键的取值,是否有打开时间控制或温度控制开关,并用于对温度和时间设定标准值,判断设定的温度与传感器读到的温度进行对比,在按键设计的逻辑中,那就是温度的检测值不能高于温度的设定值,若温度高于设定温度则继电器(模拟)停止运转,另一个逻辑是设定的时间是否到达,到达前是否已达到设定温度,时间到后不管温度升到多少都会停止加热。当温度重新检测到低于温度下限之后,又闭合继电器继续加热。只要温控开关开启热水器加热警示灯就会亮,按键按下蜂鸣器会响应提示。流程图如下:

5 设计结果及分析

在系统上电后,单击Proteus中的运行按钮,正常情况下就等待程序运行看结果,经过初始化各个模块的值为系统设置默认值。整体上由温度传感器模块采集到温度,经过低温度系数晶振或高温度系数晶振的振荡器频率受温度影响相差很大,会产生固定的频率发送给对应的计数器,从而得到位数不同分辨率不同的温度值,接下来可以通过按键设置来控制温度的设置范围和加热的时长范围,并通过对实时时间1302所得到的时间进行校准,从而可以通过对时间范围的判断和温度值的对比,确定是否需要加热水箱的水,全程的设置及温度显示均通过1602显示,其原理是找到LCD屏中点阵对应显示的内部存储的8个字节,使得相应的位置为1或0,从而组成对应的某个字符显示出来。如果出现ANALYSER ERRORS时,这时就需要检查电路的连接以及元件的选择,因为电路是有错误的,message列表中阐述了具体的错误,因此要先排错直到仿真无误后才可以完成软件仿真。

1、电源接通后显示屏进入初始化界面,显示学号和姓名。如图4-2所示:在系统上电后,或者复位按键被按下会出现初始化界面。从结果的显示可以看出,学号和名字可以分两行显示在显示屏中,比较方便。

2、初始化界面一秒后,退出界面一开始显示主界面,分别是第一行DS1302时钟记录的实时时间和第二行DS18B20传感器检测的实时温度值。可以随意设置调整当前的时间,并进行保存与设置的时间进行对比。从而可以保证在时间上的可调性与准确性。温度由传感器进行实时采集及时显示,不用手动修改调整。显示的精确度为正负一度以内。如下图4-3所示:

3、当按下设置功能键时从主界面时间开始可以更改,也就是按下设置键后可以移动光标闪烁的位置。主界面中包括小时、分钟、秒数三个,这里主界面显示的时间是根据1302时钟所获取到的,其原理是将8位地址和命令装入移位寄存器,SPI口上升沿发送下降沿接收数据。因此当按到第四下,就进入到界面二中,如下图4-4所示:此界面显示了温度的上限值up、下限值down 、开始加热时间Q、和终止加热时间Z分别对应时分两个位。可以按功能键进行光标的移动,直到到达相应的位置再分别对其进行设置。退出按键可以按下确认键。

每个按键分别被按下单次会被响应,如按下设置键到温度上限的up时,再进行温度的调整时可以按下ADD或者SUB进行温度的增大或减少,中间每按下一次设置的温度值相应的加一或减一,不论是否设置完成都可以按下确认键推出按键设置,重新回到主界面。对时间的按键操作和对温度的按键设置是完全一样的,这就是按键设置的逻辑功能。当然在设置时间或温度的同时,主界面中时钟芯片控制的时间和温度传感器发送的数据温度,也在不停的因外界环境进行着对应的变化,在设置时应确保设置的时间在主界面时间内,同时温度下限值不能高于上限值。而复位按键是当系统通信延迟或者显示异常时采取的补救措施,当按下复位按键后会重新返回初始化界面,相当于重新加载了一次程序。

 代码详细如下:

//程序头函数
#include <reg52.h>
//显示函数
#include <display.h>
#include<intrins.h>
#include<1302.h>
#include <eeprom52.h>
//宏定义
#define uint unsigned int 
#define uchar unsigned char
void jiemian_2();             //界面2 时间和温度设置界面显示
void jiemian_1();             //界面1 时间和温度读取界面显示
int shi,fen,miao; 
uint wendu; //测量的温度值
int up,down,q_shi,q_fen,z_shi,z_fen,k_1;//分别是温度上限温度下限 起始时间 终止时间  设置键->值
//管脚声明
sbit jdq= P1^0;	//继电器
sbit Feng = P2^6; //蜂鸣器
//按键
sbit Key1=P1^4;	 //设置
sbit Key2=P1^5;	 //加
sbit Key3=P1^6;	 //减
sbit Key4=P1^7;	 //确定

sbit DQ=P2^2;     			//定义DS18B20总线I/O



//时间计算
#define Imax 14000    //此处为晶振为11.0592时的取值, 
#define Imin 8000    //如用其它频率的晶振时,
#define Inum1 1450    //要改变相应的取值。
#define Inum2 700 
#define Inum3 3000 
//解码变量
unsigned char Im[4]={0x00,0x00,0x00,0x00};

//全局变量
uchar f;               //取码标志
unsigned long m,Tc;   //m对取中断码的计算     Tc中断间隔时长
unsigned char IrOK;     //判断取码是否完成
bit flag_jdq=0;         //继电器控制标志

/******************把数据保存到单片机内部eeprom中******************/
void write_eeprom()
{
	SectorErase(0x2000);
	byte_write(0x2061, up);
	byte_write(0x2062, down);
	byte_write(0x2063, q_shi);
	byte_write(0x2064, q_fen);
	byte_write(0x2065, z_shi);
	byte_write(0x2066, z_fen);
	byte_write(0x2060, a_a);	
}

/******************把数据从单片机内部eeprom中读出来*****************/
void read_eeprom()
{
	up   = byte_read(0x2061);
	down = byte_read(0x2062);
	q_shi =byte_read(0x2063);
	q_fen =byte_read(0x2064);
	z_shi =byte_read(0x2065);
	z_fen =byte_read(0x2066);
	a_a      = byte_read(0x2060);
}

/**************开机自检eeprom初始化*****************/
void init_eeprom() 
{
	read_eeprom();		//先读
	if(a_a != 1)		//新的单片机初始单片机内问eeprom
	{
		up=39;
		down=35;
		q_shi=8;
		q_fen=0;
		z_shi=17;
		z_fen=0;
		a_a = 1;
		write_eeprom();	   //保存数据
	}	
}

void delay(uint z)
{
	uint i,j;
	for(i=0;i<z;i++)
	for(j=0;j<121;j++);
}
/*****延时子程序*****/
void Delay_DS18B20(int num)
{
  while(num--) ;
}
/*****初始化DS18B20*****/
void Init_DS18B20(void)
{
  unsigned char x=0;
  DQ = 1;         //DQ复位
  Delay_DS18B20(8);    //稍做延时
  DQ = 0;         //单片机将DQ拉低
  Delay_DS18B20(80);   //精确延时,大于480us
  DQ = 1;         //拉高总线
  Delay_DS18B20(14);
  x = DQ;           //稍做延时后,如果x=0则初始化成功,x=1则初始化失败
  Delay_DS18B20(20);
}
/*****读一个字节*****/
unsigned char ReadOneChar(void)
{
  unsigned char i=0;
  unsigned char dat = 0;
  for (i=8;i>0;i--)
  {
    DQ = 0;     // 给脉冲信号
    dat>>=1;
    DQ = 1;     // 给脉冲信号
    if(DQ)
    dat|=0x80;
    Delay_DS18B20(4);
  }
  return(dat);
}
/*****写一个字节*****/
void WriteOneChar(unsigned char dat)
{
  unsigned char i=0;
  for (i=8; i>0; i--)
  {
    DQ = 0;
    DQ = dat&0x01;
    Delay_DS18B20(5);
    DQ = 1;
    dat>>=1;
  }
}
/*****读取温度*****/
unsigned int ReadTemperature(void)
{
  unsigned char a=0;
  unsigned char b=0;
  unsigned int t=0;
  float tt=0;
  Init_DS18B20();
  WriteOneChar(0xCC);  //跳过读序号列号的操作
  WriteOneChar(0x44);  //启动温度转换
  Init_DS18B20();
  WriteOneChar(0xCC);  //跳过读序号列号的操作
  WriteOneChar(0xBE);  //读取温度寄存器
  a=ReadOneChar();     //读低8位
  b=ReadOneChar();    //读高8位
  t=b;
  t<<=8;
  t=t|a;
  tt=t*0.0625;
  t= tt*10+0.5;     //放大10倍输出并四舍五入
  return(t);
}

/*
** k_1值1->界面1时, 2->界面1分, 3->界面1秒, 4==5, 5->界面2上限, 
** 6->界面2下限, 7->界面2起始时间(时),
** 8->界面2起始时间(分), 9->界面2终止时间(时), 10->界面2终止时间(分)
*/
void key()
{
   
	//模式选择
	if(Key1==0)
	{
	  delay(5);
	  if(Key1==0)
	  {
	  	Feng=0;
		  delay(100);
		  Feng=1;
	  	k_1++;
		  if(k_1==4)k_1=5;
      if(k_1==1)             //当设置键的值是1时
      {
        write_com(0x87);   //1602显示的位置
        write_com(0x0f); 
      }
      else if(k_1==2)
      write_com(0x8a);
      else if(k_1==3)
      write_com(0x8d);

      else if(k_1==4)
      write_com(0xcf);
      else if(k_1==5)
      {
      jiemian_2();
      write_com(0x84);
      }
      else if(k_1==6)
      write_com(0x8e);
      else if(k_1==7)
      write_com(0xc3);
      else if(k_1==8)
      write_com(0xc6);
      else if(k_1==9)
      write_com(0xcc);
      else if(k_1==10)
      write_com(0xcf);
      else if(k_1>10)       //当设置键超过10后,重新回到1显示界面1
      {
        ds1302write(0x8e,0x00);
      ds1302write(0x80,miao);
      ds1302write(0x82,fen);
      ds1302write(0x84,shi);
      ds1302write(0x8e,0x80);
      jiemian_1();
      write_com(0x87);
      k_1=1;                  
      }
		  while(Key1==0);

	  }
	}
	if(Key2==0&&k_1!=0)
	{
	  delay(5);
	  if(Key2==0&&k_1!=0)
	  {
	  	Feng=0;
      delay(100);
      Feng=1;
	    if(k_1==1)
	    {
        shi=shi/16*10+shi%16;
        shi++;
        if(shi==24)
        shi=0;
        write_com(0x86);
        write_data(shi/10+0x30);
        write_data(shi%10+0x30);
        write_com(0x87);
        shi=shi/10*16+shi%10;
      }
      if(k_1==2)
	    {
        fen=fen/16*10+fen%16;
        fen++;
        if(fen==60)
        fen=0;
	   	  write_com(0x89);
        write_data(fen/10+0x30);
        write_data(fen%10+0x30);
        write_com(0x8a);
        fen=fen/10*16+fen%10;
      }
		  if(k_1==3)
	    {
        miao=miao/16*10+miao%16;
        miao++;
        if(miao==60)
        miao=0;
        write_com(0x8c);
        write_data(miao/10+0x30);
        write_data(miao%10+0x30);
        write_com(0x8d);
        miao=miao/10*16+miao%10;
		  }
      if(k_1==5&&up<99)
      {
        up++;
        write_com(0x83);
        write_data(up/10+0x30);
        write_data(up%10+0x30);
        write_com(0x84);
      }
      if(k_1==6&&up-1>down)
      {
        down++;
        write_com(0x8d);
        write_data(down/10+0x30);
        write_data(down%10+0x30);
        write_com(0x8e);
      }
      if(k_1==7)
      {
        q_shi++;
        if(q_shi>23)
        q_shi=0;
        write_com(0xc2);
        write_data(q_shi/10+0x30);
        write_data(q_shi%10+0x30);
        write_com(0xc3);
      }
      if(k_1==8)
      {
        q_fen++;
        if(q_fen>59)
        q_fen=0;
        write_com(0xc5);
        write_data(q_fen/10+0x30);
        write_data(q_fen%10+0x30);
        write_com(0xc6);
      }
      if(k_1==9)
      {
        z_shi++;
        if(z_shi>23)
        z_shi=0;
        write_com(0xcb);
        write_data(z_shi/10+0x30);
        write_data(z_shi%10+0x30);
        write_com(0xcc);
      }
      if(k_1==10)
      {
        z_fen++;
        if(z_fen>59)
        z_fen=0;
        write_com(0xce);
        write_data(z_fen/10+0x30);
        write_data(z_fen%10+0x30);
        write_com(0xcf);
      }
		  while(Key2==0);
	  }
	}
	if(Key3==0&&k_1!=0)
	{
	   delay(5);
	   if(Key3==0&&k_1!=0)
	   {
	   		Feng=0;
        delay(100);
        Feng=1;
		    if(k_1==1)
		    {
			    shi=shi/16*10+shi%16;
	    	  shi--;
          if(shi<0)
          shi=23;
          write_com(0x86);
          write_data(shi/10+0x30);
          write_data(shi%10+0x30);
          write_com(0x87);
          shi=shi/10*16+shi%10;
			  }
			  if(k_1==2)
		    {
          fen=fen/16*10+fen%16;
          fen--;
          if(fen<0)
          fen=59;
          write_com(0x89);
          write_data(fen/10+0x30);
          write_data(fen%10+0x30);
          write_com(0x8a);
          fen=fen/10*16+fen%10;
			  }
			  if(k_1==3)
		    {
          miao=miao/16*10+miao%16;
          miao--;
          if(miao<0)
          miao=59;
          write_com(0x8c);
          write_data(miao/10+0x30);
          write_data(miao%10+0x30);
          write_com(0x8d);
          miao=miao/10*16+miao%10;
		  	}
        if(k_1==5&&up-1>down)
        {
          up--;
          write_com(0x83);
          write_data(up/10+0x30);
          write_data(up%10+0x30);
          write_com(0x84);
        }
        if(k_1==6&&down>0)
        {
          down--;
          write_com(0x8d);
          write_data(down/10+0x30);
          write_data(down%10+0x30);
          write_com(0x8e);
        }
        if(k_1==7)
        {
          q_shi--;
          if(q_shi<0)
          q_shi=23;
          write_com(0xc2);
          write_data(q_shi/10+0x30);
          write_data(q_shi%10+0x30);
          write_com(0xc3);
        }
        if(k_1==8)
        {
          q_fen--;
          if(q_fen<0)
          q_fen=59;
          write_com(0xc5);
          write_data(q_fen/10+0x30);
          write_data(q_fen%10+0x30);
          write_com(0xc6);
        }
        if(k_1==9)
        {
          z_shi--;
          if(z_shi<0)
          z_shi=23;
          write_com(0xcb);
          write_data(z_shi/10+0x30);
          write_data(z_shi%10+0x30);
          write_com(0xcc);
        }
        if(k_1==10)
        {
          z_fen--;
          if(z_fen<0)
          z_fen=59;
          write_com(0xce);
          write_data(z_fen/10+0x30);
          write_data(z_fen%10+0x30);
          write_com(0xcf);
        }
			  while(Key3==0);	
	    }
	}
	if(Key4==0)
	{
	  delay(5);
	  if(Key4==0)
	  { 
	  	Feng=0;
      delay(100);
      Feng=1;
	    write_com(0x0c);
	    k_1=0;
	    ds1302write(0x8e,0x00);
      ds1302write(0x80,miao);
      ds1302write(0x82,fen);
      ds1302write(0x84,shi);
      ds1302write(0x8e,0x80);
      jiemian_1();
      write_eeprom();
      while(Key4==0);
	  }
	}
		/*+++++++++++++yaokong keyiqudaio++++++++++++*/
		if(IrOK==1) 
		{
			if(Im[2]==0x0d)	//遥控设置键
			{
				Feng=0;
				delay(100);
				Feng=1;
				k_1++;
				if(k_1==4)
				k_1=5;
				if(k_1==1)
				{
				 write_com(0x87);
				 write_com(0x0f); 
				}
				else if(k_1==2)
				write_com(0x8a);
				else if(k_1==3)
				write_com(0x8d);
		
				else if(k_1==4)
				write_com(0xcf);
				else if(k_1==5)
				{
				 jiemian_2();
				 write_com(0x84);
				}
				else if(k_1==6)
				{
				 jiemian_2();
				 write_com(0x8e);
				}
				else if(k_1==7)
				write_com(0xc3);
				else if(k_1==8)
				write_com(0xc6);
				else if(k_1==9)
				write_com(0xcc);
				else if(k_1==10)
				write_com(0xcf);
				else if(k_1>10)
				{
			    ds1302write(0x8e,0x00);
          ds1302write(0x80,miao);
          ds1302write(0x82,fen);
          ds1302write(0x84,shi);
          ds1302write(0x8e,0x80);
          jiemian_1();
          write_com(0x87);
          k_1=1;
				}

				
			}
			//+键
			else if(Im[2]==0x40)
			{
				Feng=0;
				delay(100);
				Feng=1;
				if(k_1==1)
			  {
          shi=shi/16*10+shi%16;
          shi++;
          if(shi==24)
          shi=0;
			   	write_com(0x86);
          write_data(shi/10+0x30);
          write_data(shi%10+0x30);
          write_com(0x87);
          shi=shi/10*16+shi%10;
				}
				if(k_1==2)
			  {
          fen=fen/16*10+fen%16;
          fen++;
          if(fen>59)
          fen=0;
			   	write_com(0x89);
          write_data(fen/10+0x30);
          write_data(fen%10+0x30);
          write_com(0x8a);
          fen=fen/10*16+fen%10;
				}
				if(k_1==3)
			  {
          miao=miao/16*10+miao%16;
          miao++;
          if(miao>59)
          miao=0;
			   	write_com(0x8c);
          write_data(miao/10+0x30);
          write_data(miao%10+0x30);
          write_com(0x8d);
          miao=miao/10*16+miao%10;
				}
		
				if(k_1==5&&up<99)
				{
				 up++;
				 write_com(0x83);
				 write_data(up/10+0x30);
				 write_data(up%10+0x30);
				 write_com(0x84);
				}
				if(k_1==6&&up-1>down)
				{
				 down++;
				 write_com(0x8d);
				 write_data(down/10+0x30);
				 write_data(down%10+0x30);
				 write_com(0x8e);
				}
				if(k_1==7)
				{
				 q_shi++;
				 if(q_shi>23)
				 q_shi=0;
				 write_com(0xc2);
				 write_data(q_shi/10+0x30);
				 write_data(q_shi%10+0x30);
				 write_com(0xc3);
				}
				if(k_1==8)
				{
				 q_fen++;
				 if(q_fen>59)
				 q_fen=0;
				 write_com(0xc5);
				 write_data(q_fen/10+0x30);
				 write_data(q_fen%10+0x30);
				 write_com(0xc6);
				}
				if(k_1==9)
				{
				 z_shi++;
				 if(z_shi>23)
				 z_shi=0;
				 write_com(0xcb);
				 write_data(z_shi/10+0x30);
				 write_data(z_shi%10+0x30);
				 write_com(0xcc);
				}
				if(k_1==10)
				{
				 z_fen++;
				 if(z_fen>23)
				 z_fen=0;
				 write_com(0xce);
				 write_data(z_fen/10+0x30);
				 write_data(z_fen%10+0x30);
				 write_com(0xcf);
				}
			}
			//-键
			else if(Im[2]==0x19)
			{
			 if(k_1==1)
		    {
				Feng=0;
				delay(100);
				Feng=1;
				shi=shi/16*10+shi%16;
		    	shi--;
				if(shi<0)
				shi=23;
		     	write_com(0x86);
		    	write_data(shi/10+0x30);
		    	write_data(shi%10+0x30);
		    	write_com(0x87);
		    	shi=shi/10*16+shi%10;
				}
				if(k_1==2)
			    {
				fen=fen/16*10+fen%16;
			    fen--;
				if(fen<0)
				fen=59;
		     	write_com(0x89);
		    	write_data(fen/10+0x30);
		    	write_data(fen%10+0x30);
		    	write_com(0x8a);
		    	fen=fen/10*16+fen%10;
				}
				if(k_1==3)
			    {
				miao=miao/16*10+miao%16;
		     	miao--;
				if(miao<0)
				miao=59;
		    	write_com(0x8c);
			    write_data(miao/10+0x30);
			    write_data(miao%10+0x30);
			    write_com(0x8d);
			    miao=miao/10*16+miao%10;
				}
				if(k_1==4&&up-1>down)
				{
				 up--;
				 write_com(0x83);
				 write_data(up/10+0x30);
				 write_data(up%10+0x30);
				 write_com(0x84);
				}
				if(k_1==6&&down>0)
				{
				 down--;
				 write_com(0x8d);
				 write_data(down/10+0x30);
				 write_data(down%10+0x30);
				 write_com(0x8e);
				}
				if(k_1==7)
				{
				 q_shi--;
				 if(q_shi<0)
				 q_shi=23;
				 write_com(0xc2);
				 write_data(q_shi/10+0x30);
				 write_data(q_shi%10+0x30);
				 write_com(0xc3);
				}
				if(k_1==8)
				{
				 q_fen--;
				 if(q_fen<0)
				 q_fen=59;
				 write_com(0xc5);
				 write_data(q_fen/10+0x30);
				 write_data(q_fen%10+0x30);
				 write_com(0xc6);
				}
				if(k_1==9)
				{
				 z_shi--;
				 if(z_shi<0)
				 z_shi=23;
				 write_com(0xcb);
				 write_data(z_shi/10+0x30);
				 write_data(z_shi%10+0x30);
				 write_com(0xcc);
				}
				if(k_1==10)
				{
				 z_fen--;
				 if(z_fen<0)
				 z_fen=59;
				 write_com(0xce);
				 write_data(z_fen/10+0x30);
				 write_data(z_fen%10+0x30);
				 write_com(0xcf);
				} 
			}
			//确定键
			else if(Im[2]==0x15)
			{
			    Feng=0;
				delay(100);
				Feng=1;
			    write_com(0x0c);
			    k_1=0;
			    ds1302write(0x8e,0x00);
				ds1302write(0x80,miao);
				ds1302write(0x82,fen);
				ds1302write(0x84,shi);
				ds1302write(0x8e,0x80);
				jiemian_1();
				write_eeprom();
			} 
			IrOK=0;	  
		}
		/*+++++++++++++yaokong keyiqudaio++++++++++++*/
}

void jiemian_1()
{
    uchar i;
    write_com(0xc0);
	write_data('T');
	write_data('e');
	write_data('m');
	write_data('p');
	write_data('e');
	write_data('r');
	write_data('a');
   write_data('t');
   write_data('u');
   write_data('r');
   write_data('e');
	write_data(':');
	//温度显示
	i++;
	if(i>=10)
	{
	 i=0;
	wendu=ReadTemperature();
	 }
	write_data('0'+wendu/100);
	write_data('0'+wendu/10%10);
	write_data(0xdf);
	write_data(0x43);


	fen=ds1302read(0x83);
	shi=ds1302read(0x85);
	miao=ds1302read(0x81);
	write_com(0x80);
	write_data('T');
	write_data('i');
	write_data('m');
	write_data('e');
	write_data(' ');
	write_data(' ');
	write_data(shi/16+0x30);
	write_data(shi%16+0x30);
	write_data('-');
	write_data(fen/16+0x30);
	write_data(fen%16+0x30);
	write_data('-');
	write_data(miao/16+0x30);
	write_data(miao%16+0x30);
	write_data(' ');
	write_data(' ');
}
void jiemian_2()
{
  write_com(0x80);
  write_data('U');
  write_data('p');
  write_data(':');
  write_data(up/10+0x30);
  write_data(up%10+0x30);
  write_data(' ');
  write_data(' ');
  write_data(' ');
  write_data('D');
  write_data('o');
  write_data('w');
  write_data('n');
  write_data(':');
  write_data(down/10+0x30);
  write_data(down%10+0x30);
   write_com(0xc0);   //第二行显示
  write_data('Q');
  write_data(':');
  write_data(q_shi/10+0x30);
  write_data(q_shi%10+0x30);
  write_data('-');
  write_data(q_fen/10+0x30);
  write_data(q_fen%10+0x30);
   
  write_data(' ');
  write_data(' ');
  write_data('Z');
  write_data(':');
  write_data(z_shi/10+0x30);
  write_data(z_shi%10+0x30);
  write_data('-');
  write_data(z_fen/10+0x30);
  write_data(z_fen%10+0x30);
 
}

void dis_init()
{
	write_com(0x80);	//第一行显示   
	write_data('I');  //ID   :19034109
	write_data('n');
	write_data('i');
	write_data('t');
	write_data('i');
	write_data('a');
	write_data('l');
   write_data('i');
   write_data('z');
   write_data('i');
   write_data('n');
	write_data('g');
	write_data('.');
	write_data('.');
	write_data('.');
  /*
  write_com(0xc0);  //第二行
  write_data('n');
  write_data('a');
  write_data('m');
  write_data('e');
  write_data(':');
  write_data('h');
  write_data('u');
  write_data('q');
  write_data('I');
  write_data('n');
  */
}
void main()
{
     uint fen_z,fen_1,fen_q;//将分钟小时转换为十进制
	 Init1602();
	 dis_init();
	 wendu=ReadTemperature();
	 delay(2000);
	 wendu=ReadTemperature();
	
	EA=1;//打开中断总开关
	IT1=1;//下降沿有效
	EX1=1;//外部中断1开
	ET1=1;//打开允许开关
	TMOD=0x11;//设置工作方式
	
	TH0=0;//T0赋初值
	TL0=0;
	TR0=0;//t0开始计时
	
	q_shi=8;
  q_fen=0;
	z_shi=17;
	z_fen=0;
	up=39;
	down=35;
	jiemian_1();
	init_eeprom();
	read_eeprom();
	flag_jdq=jdq;
	while(1)
	{
		if(k_1==0)
		{jiemian_1();  }
	
		key();
		if(wendu>=up*10&&k_1==0)
		jdq=1;
		if(wendu<down*10&&k_1==0)
		{
		    fen_q=q_shi*60+q_fen;		   //起始时间总分钟数
			fen_z=z_shi*60+z_fen;			//终止时间总分钟数
			fen_1=(shi/16*10+shi%16)*60+fen/16*10+fen%16;	 //当前时间总分钟数
		    if(((fen_1>=fen_q&&fen_1<fen_z&&fen_q<fen_z)||(fen_q>fen_z&&(fen_1<fen_z||fen_1>=fen_q))))
	     	jdq=0;
			else 
			jdq=1;
		}
		if(jdq!=flag_jdq)
		{
			Feng=0;
			delay(1000);
			Feng=1;
			flag_jdq=jdq;
		}	
	}
}


/*+++++++++++++yaokong 遥控的中断触发 keyiqudaio++++++++++++*/
//外部中断解码程序_外部中断0
void intersvr1(void) interrupt 2 using 1
{
 TR0=1;
 Tc=TH0*256+TL0;//提取中断时间间隔时长
 TH0=0; 
 TL0=0;         //定时中断重新置零

 if((Tc>Imin)&&(Tc<Imax))
 { 
	m=0;
	f=1;
	return;
 }       //找到启始码
 if(f==1)
 {
	if(Tc>Inum1&&Tc<Inum3) 
    {
   	Im[m/8]=Im[m/8]>>1|0x80; m++; 
    }
    if(Tc>Inum2&&Tc<Inum1) 
    {
      Im[m/8]=Im[m/8]>>1; m++; //取码
  	 }
  	 if(m==32) 
    {
      m=0;  
      f=0;
      if(Im[2]==~Im[3]) 
      {
           IrOK=1;
			  TR0=0; 
   	}
      else IrOK=0;   //取码完成后判断读码是否正确
    }
               //准备读下一码
 }
}

工程文件传送门:

https://download.csdn.net/download/qq_45689245/21889722

猜你喜欢

转载自blog.csdn.net/qq_45689245/article/details/120081768