⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rili.c

📁 51环境下的1602液晶万年历程序
💻 C
字号:
//***********液晶1602显示电子万年历程序***************//
#include <reg51.h>
#include <intrins.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
//********端口定义*******
sbit rs	= P0^0;	 //lcd数据命令选择位	
sbit rw = P0^1;  //lcd写入读出选择位
sbit ep = P0^2;  //lcd使能位
sbit led=P0^3;
sbit setkey=P1^0;   //调时模式选择位
sbit setjia=P1^1;   //+1位
sbit setjian=P1^2;   //-1位
//***********变量定义************
uint year=2008;
uchar month=12,day=31,Week,hour=0,minute=0,second=0;   //设置初始显示的时间日期
uchar sec100=0;   //1秒的计数变量,加满100为1秒
uchar mod=0;      //调时标志位
uchar code tab[]={"SUN,MON,TUE,WED,THU,FRI,SAT"};

void lcd_sef_chr(); 		//自定义字符函数声明

//**********闰年月星期表
code uchar WeekTab[]= 
{							
	(3 << 5) + 31,		//1月
	(6 << 5) + 29,		//2月
	(0 << 5) + 31,		//3月
	(3 << 5) + 30,		//4月
	(5 << 5) + 31,		//5月
	(1 << 5) + 30,		//6月
	(3 << 5) + 31,		//7月
	(6 << 5) + 31,		//8月
	(1 << 5) + 30,		//9月
	(4 << 5) + 31,		//10月
	(0 << 5) + 30,		//11月
	(2 << 5) + 31 		//12月
};

/*---------------2000年~2099年星期算法--------------------------------------------*/
uchar WeekDay20(uint year, uchar m, uchar d)
{
	uchar y,week, day;
	y=year%100;
	day = WeekTab[m - 1];			//月表
	week = day >> 5;					//月星期数
	day &= 0x1f;						//月天数
	if ((m < 3) && (y & 0x03))
	{										//平年
		if (m == 2) day--;				//平年月天数
		week++;								//平年月表+1
	}
	y = y + (y >> 2);		//年+年/4
	week = (week + y + d + 2) % 7;//(星期=年+年/4+月表+2日)%7
	return (week << 5) | day;		//返回星期和月天数
}
//延时子程序----------------------------------------------------

void delay(uchar ms)
{							
	uchar i;
	while(ms--)
	{
		for(i = 0; i< 250; i++)
		{
			_nop_();
			_nop_();
			_nop_();
			_nop_();
		}
	}
}
//测试LCD忙碌状态----------------------------------------
bit lcd_bz()
{							
	bit result;
	rs = 0; 
	rw = 1;
	ep = 1;
	result = (bit)(P2 & 0x80); 	//读出lcd忙碌标志位
	ep = 0;
	return result;   					//函数返回值,返回1表示lcd忙碌,返回0表示lcd空闲
}

//写入指令数据到LCD-----------------------------------------
void lcd_wcmd(uchar cmd)
{							
	while(lcd_bz()); 					 //等待lcd到空闲
	rs = 0;
	rw = 0;
	ep = 0;
	P2 = cmd;   						//将指令写入lcd
	ep = 1;
	ep = 0;		
}

//设定显示位置子程序-----------------------------------------
void lcd_pos(uchar pos)
{							
	lcd_wcmd(pos | 0x80); 			 //将显示地址写入lcd
}

//写一个字符数据到LCD----------------------------------------
void lcd_wdat(uchar dat)	
{						
	while(lcd_bz());  				//等待lcd到空闲
	rs = 1;
	rw = 0;
	ep = 0;
	P2 = dat; 							 //将数据写入lcd
	ep = 1;
	ep = 0;	
}

//写n位数据到指定posi的位置------------------------------------
void lcd_datas(uchar posi,int dat,char n)  //在posi的位置显示名字为dat的n位数据
{
	uchar i,j,data1;
	int s;
	lcd_pos(posi);
	for(i=1;i<=n;i++)    						//从第一位开始显示,到第n位显示完毕
	{
		s=1;             
		for(j=1;j<=n-i;j++)
		s=s*10;
		data1=dat/s;
		lcd_wdat(data1+'0');
		dat=dat%s;
	}
}

//LCD初始化--------------------------------------------------
void lcd_init()
{							//LCD初始化设定
	lcd_wcmd(0x38);			//
	lcd_wcmd(0x0c);			//
	lcd_wcmd(0x06);			//
	lcd_wcmd(0x01);			//清除LCD的显示内容
}

//***显示星期程序*****
write_week(uchar week)
{
	lcd_wcmd(12 | 0x80);
	lcd_wdat(tab[4*week]);
	lcd_wdat(tab[4*week+1]);
	lcd_wdat(tab[4*week+2]);
}


//显示一屏时间------------------------------------------------
void display_lcd()
{		
	lcd_wcmd(0x01);			//清除LCD?
	delay(1);
	lcd_datas(0,year,4);	//显示第一行数据
	lcd_wdat(0X00);	
	lcd_datas(5,month,2);
	lcd_wdat(0X01);	
	lcd_datas(8,day,2);
	lcd_wdat(0X02);
	Week=WeekDay20(year, month, day)>>5;
	write_week(Week);
	lcd_datas(67,hour,2);		//显示第二行数据
	lcd_wdat(':');	
	lcd_datas(70,minute,2);
	lcd_wdat(':');	
	lcd_datas(73,second,2);	
}

//显示空字符----------------------------------------------------
void no_display(uint pos,char n)  //pos:显示的地址。n:要显示的位数
{
	lcd_pos(pos);
	while(n--)
	{
		lcd_wdat(' ');
	}
}

//年加1子程序---------------------------------------------
void inc_year()
{
   year++;
   if(year==9999)
   	year=0000;
	Week=WeekDay20(year, month, day)>>5;	
	write_week(Week);
	lcd_datas(0,year,4);
}
//月加1子程序---------------------------------------------------
void inc_month()
{
   month++;
   if(month>12)
   {
	   month=01;  
	   inc_year();
   }
	Week=WeekDay20(year, month, day)>>5;	
	write_week(Week);
	lcd_datas(5,month,2);
}
//天加1子程序-------------------------------------------
void inc_day()
{
   day++;
 	if(month==4||month==6||month==9||month==11)
    {	
     	if(day>30)
         day=01;
		inc_month();
	 }
	else if(month==2)
  	{
   	if((year%400==0)||(year%4==0)&&(year%100!=0))  
      {
	    	if(day>29)
	     	day=1;
			inc_month();
	    }
		 else if(day>28)		   
		 {
			day=1;
			inc_month();
		 }  
	 }
	else
	{
      if(day>31) 
	      day=01;
	  inc_month();
   }
	Week=WeekDay20(year, month, day)>>5;	
	write_week(Week); 
	lcd_datas(8,day,2);
}
//小时加1程序------------------------------------------------------
void inc_hour()
{
	hour++;
	if(hour > 23)
	{
		hour = 0;
      inc_day();
	}
	lcd_datas(67,hour,2);
}
//分加1程序-----------------------------------------------
void inc_min()
{
	minute++;
	if(minute > 59)
	{
		minute = 0;
		inc_hour();
	}
	lcd_datas(70,minute,2);
}
//秒加1程序-------------------------------------------
void inc_sec()
{
	second++;
	if(second > 59)
	{
		second = 0;	
		inc_min();
	}
	lcd_datas(73,second,2);
}

//调时闪动程序---------------------------------------------------
void flash()
{
	switch(mod)
	{
	case 1:		no_display(0,4);	break;
	case 2:		no_display(5,2);	break;
	case 3:		no_display(8,2);	break;
	case 4:		no_display(67,2);	break;
	case 5:		no_display(70,2);	break;
	}
}
//中断处理程序---------------------------------------------------------------
timer0() interrupt 1
{
	TH0=0xd8;
    TL0=0xf0;	
	sec100++;
	if(sec100 == 50 && mod != 0)
	    flash();
	
	if(sec100 == 92)
	{
		sec100 = 0;
		inc_sec();
		display_lcd();
	}
}

//闰年调整--------------------------------------------------------------
void incday()
{
	day++;
 	if(month==4||month==6||month==9||month==11)
    {	
     	if(day>30)
        day=01;
	 }
	else if(month==2)
  	{
   	if((year%400==0)||(year%4==0)&&(year%100!=0))  
      {
	    	if(day>29)
	     	   day=1;
	   }
		else if(day>28)
			     day=1;
	 }
	else
	{
      if(day>31) 
	     day=01;
 	 }
 }
//时间调整程序----------------------------------------------
bit inc_time()
{
	bit t;
	t=0;
	if(setjia==0)
	{   
	   delay(10);
	   if(setjia==0)
	   {
		  while(setjia==0);
          t=1;		
		 }
	 }
	return t;
}


bit dec_time()
{
	bit m;
	m=0;
	if(setjian==0)
	{   
	   delay(10);
	   if(setjian==0)
	   {
		   while(setjian==0);
         m=1;		
		}
	}
	return m;
}


//*****************主程序*************************************//

void main()
{

   TMOD=0x01;
	TH0=0xd8;
   TL0=0xf0;
   led=0;
  	lcd_init();    		//液晶初始化 
	delay(10);
	lcd_sef_chr();			//自定义字符写入液晶
	display_lcd();			//调用显示函数开始显示
	ET0=1;  
   TR0=1;
	EA=1; 
  
	while(1)
   {
//----------------------
	  if(setkey==0)
	  {   
	     delay(10);
	     if(setkey==0)
	     {
		     while(setkey==0);
           mod++;		
		     if(mod>5)
			  mod=0;
        }  
     }
//--------------------------
     if(mod==1)
	  {
		   if(inc_time()==1)
		   {
			   year++;
	         if (year==9999)
	         year=0;
				Week=	WeekDay20(year, month, day)>>5;	
				write_week(Week);
		      lcd_datas(0,year,4);
		   }
		   if(dec_time())
		   {
		      year--;
				Week=WeekDay20(year, month, day)>>5;	
				write_week(Week);
		      lcd_datas(0,year,4);
		   }
      }
//----------------------------------
      else if(mod==2)
	  {	 
		   if(inc_time()==1)
		   {
			  month++;
	        if(month>12)
	        month=1;
				Week=	WeekDay20(year, month, day)>>5;	
				write_week(Week);
			  lcd_datas(5,month,2);
		   }
		   if(dec_time())
		   {
		      month--;
	         if(month==0)
	         month=12;
				Week=	WeekDay20(year, month, day)>>5;	
				write_week(Week);
		      lcd_datas(5,month,2);
		   }
      }
//----------------------------------
		else if(mod==3)
   	{	 
	  		if(inc_time()==1)
	    	{
				incday();
				Week=	WeekDay20(year, month, day)>>5;
				write_week(Week);
		    	lcd_datas(8,day,2);
	     	}		

 	 		if(dec_time())
			{
	     		day--;
       	 	if(month==4||month==6||month==9||month==11)
    	    	{	
     	     		if(day==0)
             		day=30;
		    	}

				else if(month==2)
  		 		{
   				if((year%400==0)||(year%4==0)&&(year%100!=0))  
      		 	{
	    				if(day==0)
	     				   day=29;
	    	 		}
					else if(day==0)
						day=28;
	    		}
				else
	  			{
      			if(day==0) 
	  				   day=31;
	   		}
				Week=	WeekDay20(year, month, day)>>5;
				write_week(Week);
				lcd_datas(8,day,2);
			}
 	 }
//------------------------------------------
	  else if(mod==4)
	  {	 
	     if(inc_time()==1)
	     {
		     hour++;
           if(hour==24)
              hour=0;	
		     lcd_datas(67,hour,2);
	     }
	     if(dec_time())
	     {
	        hour--;
           if(hour>23||hour<0)
              hour=23;
	        lcd_datas(67,hour,2);
	     }
     }

      else if(mod==5)
	   {	 
	     if(inc_time()==1)
	     {
	      	minute++;
            if(minute==60)
               minute=0;
		      lcd_datas(70,minute,2);
	  	  }
	     if(dec_time())
	     {
	        minute--;
           if(minute>60)
              minute=59;
	        lcd_datas(70,minute,2);
	     }
	  }
  }   //while

}   //main


void lcd_sef_chr()
{	
	//第一个自定义字符-年
	lcd_wcmd(0x40);	//"01 000 000"  第1行地址 (D7D6为地址设定命令形式

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -