📄 基于液晶显示的万年历.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 + -