基于LCD1602的多功能万年历,温湿度计,非RTC时钟芯片单片机技术

很久前做过的一个电子万年历,拿来和大家分享一下,做成实物在家里放着跑了2年多了,极其稳定,日误差小于1秒。

唯一的问题:不用DS1302虽然是省去了不少焊接的功夫,但是程序掉电又得重设时间,所以建议接交流电+蓄电池浮充,这样就不会掉电了,完美解决问题,可以跑一个月都不用调时间。

 

源代码:

#include <reg52.h>		                                   
typedef  unsigned int u16;	 
typedef  unsigned char u8; 
sbit k2=P3^2;                                            //K1 K2 K3 K4按键接口,建议从左到右接K1-K4
sbit k1=P3^5;
sbit k3=P3^3;
sbit k4=P3^4;
sbit DQ=P3^6;
sbit beep=P1^6;    
sbit Data=P2^0;                                             //有源蜂鸣器在P16口
sbit lcden=P1^4;                                                //LCD1602接口定义
sbit lcdrs=P1^0;                                                   
sbit lcdrw=P2^6;
sbit bg=P2^7;                                                //背光变量接入LCD1602的K极,通过bg的高低电平就可控制自动熄灭与点亮
u8 k,e,d,o=1,p=1,temp,nxflag=0,mbflag=0,tianmax;      
float temperature;                                           //温度变量,18B20接收时为浮点数
u8 miao1,miao2,fen1,fen2,shi1,shi2,tian1,tian2,wk,tem1,tem2,tem3,wendufu;
u8 day=1,mon=1,day1,day2,yue1,yue2,mbw,n=0,m=0,beiguang,RH,RL,TH,TL,tempH,tempL;
u8 se1,se2,mon1,mon2,hou1,hou2,min1,min2,MB2,nian1,nian2,nian3,nian4; 
u16 y,MB1;
u16 temper,buchang,tempwarn=0,tempwarn1=500;                //tempwarn为温度下限,1为温度上限
u8 code set[]={"NaoZhong  Status"};                                    //上电后傻瓜调节模块
u8 code tempwarng[]={"Wendu Waring!"};
u8 code temmin[]={"Min"};
u8 code temmax[]={"Max"};                
u8 code naozhongON[]={" ON"};
u8 code naozhongOFF[]={"OFF"};
u8 code setsucces[]={"Set Success!"};
u8 code thanks[]={"Welcome to use !"};
u8 code thanksu[]={"thanks for using"};
u8 code make[]={"Designed by LY"};
u8 code MB[]={"Stopwatch"};
u8 code week1[]={"[MON]"};
u8 code week2[]={"[TUE]"};
u8 code week3[]={"[WED]"};
u8 code week4[]={"[THU]"};
u8 code week5[]={"[FRI]"};
u8 code week6[]={"[SAT]"};
u8 code week7[]={"[SUN]"};                        
void delay(unsigned int z)                                   //定义延时函数
{                                           
  unsigned int x,y;			
  for(x=z;x>0;x--)
  for(y=1;y>0;y--);
}
void DHT11_delay_us(u8 n)
{
    while(--n);
}
void DHT11_delay_ms(u16 z)               //定义DHT11延迟函数
{
   u16 i,j;
   for(i=z;i>0;i--)
      for(j=110;j>0;j--);
}

	 void DHT11_start()
{
   Data=1;
   DHT11_delay_us(2);
   Data=0;
   DHT11_delay_ms(20);   //延时18ms以上
   Data=1;
   DHT11_delay_us(30);
}
u8 DHT11_rec_byte()      //接收一个字节
{
  u8 i,dat=0;
  for(i=0;i<8;i++)       //从高到低依次接收8位数据
   {          
      while(!Data);       //等待50us低电平过去
      DHT11_delay_us(8);   //延时60us,如果还为高则数据为1,否则为0 
      dat<<=1;           //移位使正确接收8位数据,数据为0时直接移位
      if(Data==1)        //数据为1时,使dat加1来接收数据1
         dat+=1;
      while(Data);       //等待数据线拉低    
    }  
    return dat;
}
void DHT11_receive()      //接收40位的数据
	{
    u8 R_H,R_L,T_H,T_L,revise; 
    DHT11_start();
    if(Data==0)
    {
        while(Data==0);   //等待拉高     
        DHT11_delay_us(40);      //拉高后延时80us
        R_H=DHT11_rec_byte();    //接收湿度高八位  
        R_L=DHT11_rec_byte();    //接收湿度低八位  
        T_H=DHT11_rec_byte();    //接收温度高八位  
        T_L=DHT11_rec_byte();    //接收温度低八位
        revise=DHT11_rec_byte(); //接收校正位
        DHT11_delay_us(25);      //结束
        if((R_H+R_L+T_H+T_L)==revise)      //校正
        {
            RH=R_H;
            RL=R_L;
			TH=T_H;
			TL=T_L;
        } 
    }
  }
void beepon()                                                //PWM(如果你是无源蜂鸣器,这里写PWM函数)
{	                                                     //当前为有源蜂鸣器,有源蜂鸣器无需更改
   beep=0;
   delay(1200);
   beep=1;     
}	 
void write_nian();                                  //预定义
void write_yue();
void write_tian();
void write_shi();
void write_fen();
void write_miao();
void write_week();
void zhuanhuan();
void write_temp();
void write_nz();
void nzON();
void write_setsuccess();
void beiguangpd();

void write_com(u8 com)                                    //LCD1602初始化程序,了解1602时序图后新手的话可以直接照搬使用                                     
{
 lcdrs=0;
 P0=com;
 delay(5);
 lcden=1;
 delay(5);
 lcden=0;
}
void write_data(u8 date)
{
 lcdrs=1;
 P0=date;
 delay(5);
 lcden=1;
 delay(5);
 lcden=0;
}
void init()
{
 lcdrw=0;
 lcden=0;
 write_com(0x38);
 write_com(0x0c);
 write_com(0x06);
 write_com(0x01);
 write_com(0x80+0x10);  
}	
void Timer0Init()	                                            //定时器0工作方式1 中断初始化,923位12M晶振在KEIL仿真后的计算结果
{   
    TMOD=0X01;
	TH0=(65535-901)/256;	
	TL0=(65535-901)%256;	
	ET0=1;                                          //打开定时器0中断允许位
	EA=1;                                         //打开总中断允许
	TR0=1;			                         //打开 定时器0,开始计时
}
 Init_DS18B20(void)                                    //DS18B20初始化与时序图程序,仿真时温度问题改进这个初始化程序就解决了
  { 
       DQ=1;
       delay(70); 
       DQ=0; 
       delay(485); 
       DQ=1; 
       delay(50); 
  } 
ReadOneChar(void)                                      //18B20读一个字节 
  {  
    unsigned char i=0; 
    unsigned char dat=0; 
       for (i=8;i>0;i--) 
     { 
         DQ=1; 
         delay(1); 
         DQ=0; 
         dat>>=1; 
         DQ=1; 
         if(DQ) 
         dat|=0x80; 
         delay(4); 
       } 
    return(dat); 
   }  
WriteOneChar(unsigned char dat)                     //18B20写一个字节
   { 
         unsigned char i=0; 
         for(i=8;i>0;i--) 
        { 
             DQ=0; 
             DQ=dat&0x01; 
             delay(5); 
             DQ=1; 
             dat>>=1; 
        } 
          delay(4); 
    } 
ReadTemperature(void)                           //读取温度函数定义,返回值为浮点数
   { 
        Init_DS18B20(); 
        WriteOneChar(0xcc); 
        WriteOneChar(0x44); 
        delay(125); 
        Init_DS18B20(); 
        WriteOneCha
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值