基于单片机的液晶日历时钟
本设计利用单片机AT89S52和1602液晶,实现日历(年月日)、星期和时间的显示。具体效果为:
2011-11-11 FRI
11:11:11
二、设计图纸
1、电路原理图
2、PCB图
3、三维模型
三、相关程序
程序简介:程序启动后,先初始化液晶和两个定时器,时钟开始工作,再进入扫描检测调整时钟函数中,根据是否有KEY1长按来决定是否调整时钟。定时器T0用来产生时钟计时,T1用来中断显示液晶,按键KEY1为多功能按键,在时钟工作时,长按时进入时钟调整,依次调整年、月、日、星期、时、分,KEY2和KEY3分别为上下调整,每次调整完毕后短按KEY1返回,进入下一个调整。
1、主程序文件
#include "reg51.h"
#include "adjust.h"
#include "lcm.h"
#include "key.h"
//定时器初始化函数
void Timer_Start()
{
TMOD=0x11;
TH1=0xfc;
TL1=0x18;
TH0=0xfc;
TL0=0x60;
EA=1;
ET1=1;
ET0=1;
TR1=1;
TR0=1;
}
//主函数
void main()
{
unsigned char Key_Code;
//初始化LCM
LCM_START();
//初始化定时器
Timer_Start();
while(1)
{
Key_Code=Key_Scan();
switch(Key_Code)
{
case Key_M:Adjust();break;
default:break;
}
}
}
2、延时程序文件
(1)头文件
#ifndef __DELAY_H__
#define __DELAY_H__
extern void Delay_ms(unsigned int ms);
#endif
(2)程序文件
#include "delay.h"
//延时1毫秒函数
void Delay_ms(unsigned int ms)
{
unsigned char Temp;
while(ms--)
for(Temp=0;Temp<120;Temp++);
}
2、时钟程序文件
(1)头文件
#ifndef __CLOCK_H__
#define __CLOCK_H__
extern unsigned int Second_Count;
extern char Second;
extern char Minute;
extern char Hour;
extern char Day;
extern char Month;
extern int Year;
extern char Week;
extern char Month_Day[12];
extern bit Leap_Year(int Temp_Year);
#endif
(2)程序文件
#include "reg51.h"
//秒计数变量
unsigned int Second_Count=0;
//时分秒变量
char Second=53;
char Minute=20;
char Hour =5;
char Day =18;
char Month =4;
int Year =2011;
char Week =1;
//每月天数数组
char Month_Day[12]={31,28,31,30,31,30,31,31,30,31,30,31};
//闰年判断函数
bit Leap_Year(int Temp_Year)
{
bit Temp;
if(((Temp_Year%4==0)&&(Temp_Year%100!=0))||(Temp_Year%400==0))
{
Temp=1;
}
else
{
Temp=0;
}
return Temp;
}
//定时器0中断服务函数
void Timer0_Serve()interrupt 1
{
TH0=0xfc;
TL0=0x60;
Second_Count++;
if(Second_Count>1000)
{
Second_Count=0;
Second++;
if(Second>=60)
{
Second=0;
Minute++;
if(Minute>=60)
{
Minute=0;
Hour++;
if(Hour>=24)
{
Hour=0;
Week++;if(Week>=7)Week=0;
Day++;
if(Day>Month_Day[Month-1])
{
if((Month!=2)||(!Leap_Year(Year))||(Day>29))
{
Day=1;
Month++;
if(Month>12)
{
Month=1;
Year++;
}
}
}
}
}
}
}
}
3、液晶程序文件
(1)头文件
#ifndef __LCM_SHOW_H__
#define __LCM_SHOW_H__
extern void LCM_START();
extern void LCM_CMD (unsigned char Temp_Data);
extern void LCM_DATA(unsigned char Temp_Data);
extern void LCM_POS (unsigned char Temp_Data);
#endif
(2)程序
#include "reg51.h"
#include "delay.h"
#include "intrins.h"
//LCM控制端口定义
sbit RS=P2^5;//数据/命令选择端口
sbit RW=P2^6;//读写控制端口
sbit EN=P2^7;//使能端口
//定义商标字符
char code Logo1[]="WELCOME TO";
char code Logo2[]="MY MCU WORKSHOP!";
//LCM状态读取函数
bit LCM_Status()
{
bit Temp_Status;
RS=0;
RW=1;
EN=1;
_nop_();
Temp_Status=(bit)(P0&0x80);
_nop_();
EN=0;
return Temp_Status;
}
//LCM写初始化命令函数
void LCM_INIT(unsigned char Temp_Data)
{
RS=0;
RW=0;
EN=0;
_nop_();
P0=Temp_Data;
_nop_();
EN=1;
_nop_();
_nop_();
EN=0;
}
//LCM写命令函数
void LCM_CMD(unsigned char Temp_Data)
{
while(LCM_Status());
RS=0;
RW=0;
EN=0;
_nop_();
P0=Temp_Data;
_nop_();
EN=1;
_nop_();
_nop_();
EN=0;
}
//LCM写数据函数
void LCM_DATA(unsigned char Temp_Data)
{
while(LCM_Status());
RS=1;
RW=0;
EN=0;
_nop_();
P0=Temp_Data;
_nop_();
EN=1;
_nop_();
_nop_();
EN=0;
}
//LCM显示位置设定函数
void LCM_POS(unsigned char Temp_Data)
{
LCM_CMD(Temp_Data|0x80);
}
//LCM初始化函数
void LCM_START()
{
unsigned char Temp;
//写初始化指令三次但不检测忙信号
LCM_INIT(0x38);
Delay_ms(5);
LCM_INIT(0x38);
Delay_ms(5);
LCM_INIT(0x38);
Delay_ms(5);
//写初始化命令字
LCM_CMD(0x38);
Delay_ms(1);
//写清屏命令字
LCM_CMD(0x01);
Delay_ms(1);
//写地址指针及光标自动移位命令字
LCM_CMD(0x06);
Delay_ms(1);
//写开显示命令字
LCM_CMD(0x0c);
Delay_ms(1);
单片机液晶日历时 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)