单片机定时器实现实时时钟程序-lcd1602显示
下面是程序的源代码:
/**
*功能:在LCD1602上显示当前时间(Time)和日期(Date)
* 自动计时,可计时年月日(包括平年和闰年)
* 可用按键调整时间和日期
* L *****************************
* C * Time: 00 Date: *
* D * 00:00 2013-06-05 *
* ******************************
*作者:徐冉
*日期:2013-06-05-19:10-22:50~2013-06-06-07:20-10:20
*备注:此程序已经通过调试,已做修改。耗时:5小时30分钟
**/
/****************AT89C52-RC MCU******************************/
/********************51hei单片机实验板****************************/
#include
typedef unsigned int uint;
typedef unsigned char uchar;
sbit RS = P1^0;
sbit RW = P1^1;
sbit EN = P2^5;
sbit wela = P2^7;
sbit dula = P2^6;
sbit BUSY = P0^7;
sbit FM = P2^3;
uchar counter,tshi, tfen, tmiao;
uchar sshi, sge, fshi, fge, mshi, mge;
uint nian;
uchar yue, ri;
uchar nqian, nbai, nshi, nge, yshi, yge, rshi, rge;
uchar code time[] = "Time:";
uchar code date[] = "Date:";
//delay:xms
void delay(uint xms)
{
uchar i, j;
for(i = 0; i < xms; i++)
for(j = 0; j < 125; j++);
}
//wait:
void wait()
{
P0 = 0xff;
RS = 0;
RW = 1;
EN = 0;
EN = 1;
while(BUSY == 1);
EN = 0;
}
//write:cmd
void write_cmd(uchar cmd)
{
wait(); //写数据和命令时,必须进行判忙等待!!!
RS = 0;
RW = 0;
EN = 0;
P0 = cmd;
EN = 1;
EN = 0;
}
//write:data
void write_data(uchar dat)
{
wait();//写入数据之前必须进行判忙等待,否则数据将写入不成功!!!
RS = 1;
RW = 0;
EN = 0;
P0 = dat;
EN = 1;
EN = 0;
}
//LCD1602:init
void init()
{
nian = 2013;
yue = 6;
ri = 5;
wela = 0;
dula = 0;
P1 = 0xff;
delay(10);
write_cmd(0x38);
delay(5);
write_cmd(0x38);
delay(5);
write_cmd(0x38);
wait();
write_cmd(0x38);
wait();
write_cmd(0x0c);
wait();
write_cmd(0x06);
wait();
write_cmd(0x01);
}
//timer1:init
void timer1_init()
{
TMOD = 0x10;
TH1 = 0xB8;
TL1 = 0x00;
TR1 = 1;
EA = 1;
ET1 = 1;
}
//write:byteaddress
void write_pos(uchar add)
{
write_cmd(add| 0x80);
}
//write:string
void send_string(uchar *str)
{
while(*str != )
{
write_data(*str++);
}
}
//dis:date
void dates()
{
nqian = nian / 1000 % 10;
nbai = nian / 100 % 10;
nshi = nian / 10 % 10;
nge = nian % 10;
yshi = yue / 10 % 10;
yge = yue % 10;
rshi = ri / 10 % 10;
rge = ri % 10;
write_pos(0x00);
send_string(time);
write_pos(0x09);
send_string(date);
write_pos(0x46);
write_data(nqian + 0x30);
write_pos(0x47);
write_data(nbai + 0x30);
write_pos(0x48);
write_data(nshi + 0x30);
write_pos(0x49);
write_data(nge + 0x30);
write_pos(0x4A);
write_data(-);
write_pos(0x4B);
write_data(yshi + 0x30);
write_pos(0x4C);
write_data(yge + 0x30);
write_pos(0x4D);
write_data(-);
write_pos(0x4E);
write_data(rshi + 0x30);
write_pos(0x4F);
write_data(rge + 0x30);
}
//dis:time
void times()
{
sshi = tshi / 10 % 10;
sge = tshi % 10;
fshi = tfen / 10 % 10;
fge = tfen % 10;
mshi = tmiao / 10 % 10;
mge = tmiao % 10;
write_pos(0x40);
write_data(sshi + 0x30);
write_pos(0x41);
write_data(sge + 0x30);
write_pos(0x43);
write_data(fshi + 0x30);
write_pos(0x44);
write_data(fge + 0x30);
write_pos(0x06);
write_data(mshi + 0x30);
write_pos(0x07);
write_data(mge + 0x30);
}
//keyscan:
void marixKeyscan()
{
uchar temp;
P3 = 0xfe;
temp = P3;
temp &= 0xf0;
if(temp != 0xf0)
{
delay(5);
temp = P3;
temp &= 0xf0;
if(temp != 0xf0)
{
FM = 0;
temp = P3;
switch(temp)
{
case 0xee: tshi++; if(tshi >= 24) tshi = 0; break;
case 0xde: tfen++; if(tfen >= 60) tfen = 0; break;
case 0xbe: nian++; if(nian >= 10000) nian = 0; break;
case 0x7e: yue++; if(yue >= 13) yue = 1; break;
}
while(temp != 0xf0)
{
temp = P3;
temp &= 0xf0;
}
delay(2);
while(temp != 0xf0)
{
temp = P3;
temp &= 0xf0;
}
FM = 1;
}
}
P3 = 0xfd;
temp = P3;
temp &= 0xf0;
if(temp != 0xf0)
{
delay(5);
temp = P3;
temp &= 0xf0;
if(temp != 0xf0)
{
FM = 0;
temp = P3;
switch(temp)
{
case 0xed: ri++; if(yue == 1 || yue == 3 || yue == 5 || yue == 7 || yue == 8 || yue == 10 || yue == 12 )
{
if(ri >= 32)
{
ri = 1;
}
}
if(yue == 4 || yue == 6 || yue == 9 || yue == 11)
{
if(ri >= 31)
{
ri = 1;
}
}
if(yue == 2)
{
if(((nian % 4 == 0) && (nian % 100) != 0) || (nian % 400 == 0))
{
if(ri >= 30)
{
ri = 1;
}
}
else
{
if(ri >= 29)
{
ri = 1;
}
}
}
break;
case 0xdd: tshi--; if(tshi <= 0) {tshi = 23;} break;
case 0xbd: tfen--; if(tfen <= 0) {tfen = 59;} break;
case 0x7d: nian--; if(nian <= 0) {nian = 10000;} break;
}
while(temp != 0xf0)
{
temp = P3;
temp &= 0xf0;
}
delay(2);
while(temp != 0xf0)
{
temp = P3;
temp &= 0xf0;
}
FM = 1;
}
}
P3 = 0xfb;
temp = P3;
temp &= 0xf0;
if(temp != 0xf0)
{
delay(5);
temp = P3;
temp &= 0xf0;
if(temp != 0xf0)
{
FM = 0;
temp = P3;
switch(temp)
{
case 0xeb:
ri--;
if(yue == 1 || yue == 3 || yue == 5 || yue == 7 || yue == 8 || yue == 10 || yue == 12 )
{
if(ri <= 0)
{
ri = 31;
}
}
if(yue == 4 || yue == 6 || yue == 9 || yue == 11)
{
if(ri <= 0)
{
ri = 30;
}
}
if(yue == 2)
{
if(((nian % 4 == 0) && (nian % 100) != 0) || (nian % 400 == 0))
{
if(ri <= 0)
{
ri = 29;
}
}
else
{
if(ri <= 0)
{
ri = 28;
}
}
break;
case 0xdb: tshi = 0;
tfen = 0;
tmiao = 0;
nian = 0;
yue = 1;
ri = 1;
break;
}
while(temp != 0xf0)
{
temp = P3;
temp &= 0xf0;
}
delay(2);
while(temp != 0xf0)
{
temp = P3;
temp &= 0xf0;
}
}
FM = 1;
}
}
}
//main:
void main(void)
{
init();
timer1_init();
write_pos(0x42);
write_data(:);
write_pos(0x06);
write_data(-);
while(1)
{
times();
dates();
marixKeyscan();
if(counter == 50)
{
counter = 0;
tmiao++;
if(tmiao >= 60)
{
tmiao = 0;
tfen++;
if(tfen >= 60)
{
tfen = 0;
tshi++;
if(tshi >= 24)
{
tshi = 0;
ri++;
switch(yue)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12: if(ri >= 32)
{
ri = 1;
yue++;
}
break;
case 4:
case 6:
case 9:
case 11: if(ri >= 31)
{
ri = 1;
yue++;
}
break;
case 2: if(((nian % 4 ) == 0 && (nian % 100) != 0) || (nian % 400 == 0))
{
if(ri >= 30)
{
ri = 1;
yue++;
}
}
else
{
if(ri >= 29)
{
ri = 1;
yue++;
}
}
break;
default: break;
}
if(yue >= 13)
{
yue = 1;
nian++;
if(nian >= 10000)
{
nian = 0;
}
}
}
}
}
}
}
}
//timr1:int
void timer1_int() interrupt 3
{
TH1 = 0xB8;
TL1 = 0x00;
counter++;
}
单片机定时器实时时钟lcd1602显 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)