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

📄 基于液晶显示的万年历.c

📁 一个实用的万年历程序
💻 C
字号:
/*
实验项目:基于AT89S52单片机的时钟,日历,整点报时及温度显示
 描述:本实验通过单片机内部晶振实现时钟,由DS18B20实现温度采集.实验中采用10位键输入方式,利用74HC148编码键盘输入.
 全部输出由LCD1602显示,电源部分采用掉电工作方式,实现了时间信息的掉电保护,使在掉电状态下单片机时钟仍然工作。
 
 操作说明:

 键盘中 P3.0,P3.1,P3.2,P3.3	端口依次为时间调整总开关,闹钟调整总开关,报时接口,闹钟接口
		 
		 P1端口按键功能依次为 年,月,日,星期,时钟,分钟,闹钟时钟,闹钟分钟调整键

		 P0口为液晶数据输出口中

		 P2.0,P2.1,P2.2 依次为液晶RW,RS,E 接口
*/
#include <reg51.h>
#include <intrins.h>
#define Key P1
sbit  key_date=P3^0; 
sbit  K_show = P3^1;
sbit alarm_time=P3^2;
sbit alarm=P3^3;
bit scan_key(void);
void proc_key(void);
extern void LCD_WriteCommand(unsigned char cmd);	 //写指令数据到LCD
extern void LCD_DisplayOneString(unsigned char X,unsigned char Y,unsigned char a[]);//显示一个字符串
extern void LCD_DisplayNum(unsigned charX,unsigned char Y,unsigned char num);       //显示一个数字						      //外部函数声明区
extern void LCD_Init(void);	//LCD初始化
extern void delayus(unsigned int num);  //液晶延时
void delayms(unsigned char ms);  //键盘延时
extern void LCD_DisplayOneChar(unsigned char X,unsigned char Y,unsigned char Z);//显示一个字符
extern unsigned char ReadTemperature(void);

unsigned char hour,min,sec,year,mon,day,week0,temp0,ahour,amin;
unsigned char test,record;
unsigned char sec100;
unsigned char code week[]={"week"};
unsigned char code temp[]={"temp"};

void main(void)
{   unsigned char show_con=0;
    alarm_time=0;
	alarm=0;
    TMOD = 0x11;		// 定时器0, 1工作模式1, 16位定时方式
	TH0 =(65536-50000)/256;
	TL0 =(65536-50000)%256;
	TH1 = 0xFC;
	TL1 = 0x17;
    hour = 23;
	min =59;
	sec = 57;
	year=0;
	mon=10;
	day=1;
	ahour=12;amin=00;
	week0=1;
	sec100 = 0;
	IE = 0x8A;				// 使能timer0,1 中断
	TR0=1;
	TR1=1;
			 
	record=0xff;
	LCD_Init();
	LCD_WriteCommand(0x01);
	while(1)
	{ 
	temp0=ReadTemperature();//读温度 
	 
	  if(K_show==0)
	  { 
	    if(show_con==0) { LCD_WriteCommand(0x01);show_con=1;}
	    delayms(10);
		LCD_DisplayNum(2,0,ahour);
	    LCD_DisplayOneChar(4,0,0xB0);					   //显示闹钟时间
	    LCD_DisplayNum(5,0,amin);
	 }
	 else 
	  {	LCD_WriteCommand(0x0C);
	    LCD_WriteCommand(0x06);
	    LCD_DisplayOneString(9,0,temp);
	    LCD_DisplayOneChar(13,0,0x3a);
	    LCD_DisplayNum(14,0,temp0); 				   //显示时间,月历,星期及当前温度
	    LCD_DisplayOneString(9,1,week);
	    LCD_DisplayNum(0,0,hour);			
	    LCD_DisplayOneChar(2,0,0xB0); 
        LCD_DisplayNum(3,0,min);
	    LCD_DisplayOneChar(5,0,0xB0); 
        LCD_DisplayNum(6,0,sec);
		LCD_DisplayNum(0,1,year);
	    LCD_DisplayOneChar(2,1,0x2f); 
	    LCD_DisplayNum(3,1,mon);
	    LCD_DisplayOneChar(5,1,0x2f);
	    LCD_DisplayNum(6,1,day);
	    LCD_DisplayOneChar(13,1,0x3a); 
	    LCD_DisplayOneChar(14,1,(week0+0x30));
	    show_con=0;
	  }
 	   if(scan_key())
	   { 
	    delayms(10);
	    if(scan_key())
		{ record=test;
		  proc_key();
		}
	  }
	  
	}
  }
void timer1() interrupt 1 using 2		//定时工作,作为时钟
{	 unsigned int i,j;
     i=year+2000;
	TH0 =(65536-50000)/256;
	TL0 =(65536-50000)%256;
	sec100++;
	if(sec100>=20)
	{  sec100=0;
		sec++;
		if(sec>59)
		{ sec=0;if(min==59){alarm_time=1;for(j=20;j>0;j--){}alarm_time=0;} //报时响应
		   min++;
		  if(min>59)
		  { min=0;			 //变换时间
		    hour++;
			if(hour>23)
			{ hour=0;
			  day++;
			  week0++;
			  if(week0>6) week0=0;
			  switch(mon)
			  { case 2:	if(i%4==0&&i%100!=0||i%400==0) if(day>28){day=1;mon++;if(mon>12){mon=1;year++;}} break;
			            if(day>29){day=1;mon++;if(mon>12){mon=1;year++;}} break;
			    case 1:	if(day>31){day=1;mon++;if(mon>12){mon=1;year++;}} break;
			    case 3:	if(day>31){day=1;mon++;if(mon>12){mon=1;year++;}} break;
			    case 5:	if(day>31){day=1;mon++;if(mon>12){mon=1;year++;}} break;
			    case 7:	if(day>31){day=1;mon++;if(mon>12){mon=1;year++;}} break;
			    case 8:	if(day>31){day=1;mon++;if(mon>12){mon=1;year++;}} break;
			    case 10:if(day>31){day=1; mon++;if(mon>12){mon=1;year++;}} break;
                case 12:if(day>31){day=1;mon++;if(mon>12){mon=1;year++;}} break;
			   	default:if(day>30){day=1;mon++;if(mon>12){mon=1;year++;}} break;
			  }

			}
		  }
		}
	  }
}
//键盘部分程序
void delayms(unsigned char ms)	
{  unsigned char i;
	while(ms--)
	{
		for(i = 0; i < 120; i++);
	}
}
bit scan_key()
{
 test=Key;
 return(test ^ record);	
}

 void proc_key()
{
	EA = 0;
	
 switch(~test)
 { case 0x01: if(!key_date)year++;break;
   case 0x02: if(!key_date)mon++;if(mon>12) mon=0;break;
   case 0x04: if(!key_date)day++;if(day>31) day=0;break;
   case 0x08: if(!key_date)week0++;if(week0>6) week0=0;break;
   case 0x10: if(!key_date)hour++; if(hour>23) hour=0;break;
   case 0x20: if(!key_date)min++;if(min>59) min=0;break;
   case 0x40: if(K_show==0) ahour++; if(ahour>23) ahour=0;break;
   case 0x80: if(K_show==0) amin++;if(amin>59) amin=0;break;
 }

	EA = 1;
}
//闹钟部分中断响应
void searchtime() interrupt 3 using 1
{ 	TH1 = 0xFC;
	TL1 = 0x17;
	if((ahour==hour)&&(amin==min))
	alarm=1;
	else 
	alarm=0;
} 

⌨️ 快捷键说明

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