标签:
单片机
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit rs=P1^0;
sbit rw=P1^1;
sbit e=P1^2;
sbit s1=P3^2;//按键s1,s2,s3分别接到P3^2,P3^3,P3^0
sbit s2=P3^3;
sbit s3=P3^0;
sbit rd=P3^4;//初始化中置0
uchar num,t,shi,fen,miao,s1num,s2num,s3num;
uchar code table2[]="MonWedTueThuFriSatSun";//星期
uchar code table3[]={31,29,31,30,31,30,31,31,30,31,30,31};//闰年
uchar code table4[]={31,28,31,30,31,30,31,31,30,31,30,31};//平年
uint nian,yue,ri;
uchar t1;//
uchar code table[]=" 2008-10-03 Fri";
uchar code table1[]=" 00:00:00";
/********************************
延时
********************************/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=10;y>0;y--);
}
/********************************
写指令
********************************/
void write_com(uchar com)
{
rs=0;
P0=com;
delay(5);
e=1;
delay(5);
e=0;
}
/********************************
写数据
********************************/
void write_data(uchar date)
{
rs=1;
P0=date;
delay(5);
e=1;
delay(5);
e=0;
}
/********************************
中断,被初始化函数调用
********************************/
void zduan()
{
TMOD=0x01;
TH0=(65536-50000)/256;//装初值
TL0=(65536-50000)%256;
EA=1;//开总中断
ET0=1;//开T0中断
TR0=1;//启动计数器T0
}
/********************************
初始化
********************************/
void init()
{
nian=2008;//初始化年,月,日
yue=10;
ri=3;
t1=12;//初始化星期,12是表示为星期五
rd=0;//按键s3一端接P3^4,设置为低电平,相当接地
rw=0;
write_com(0x38);//设置16*2显示,5*7点阵,8为数据接口
write_com(0x0c);//开显示,不显示光标
write_com(0x06);//当读或写一个字符后地址指针加一,且光标加一,整屏显示不移动
write_com(0x01);//显示清屏
write_com(0x80);
for(num=0;num<16;num++)//写入初始显示的年,月,日,星期
{
write_data(table[num]);
delay(5);
}
write_com(0x80+0x40);
for(num=0;num<12;num++)//写入初始显示的时,分,秒
{
write_data(table1[num]);
delay(5);
}
zduan();//调用初始化函数
}
/********************************
写入年
********************************/
void write_nian(uint nian)
{
uint qw,bw,sw,gw;
qw=nian/1000;
bw=nian%1000/100;
sw=nian%1000%100/10;
gw=nian%10;
write_com(0x80+0x02);//指向对应地址
write_data(0x30+qw);
write_data(0x30+bw);//延时?
write_data(0x30+sw);
write_data(0x30+gw);
}
/********************************
写入日,月
********************************/
void write_ry(uint add,uint ry)
{
uint sw,gw;
sw=ry/10;
gw=ry%10;
write_com(0x80+add);//指向对应地址
write_data(0x30+sw);
write_data(0x30+gw);
}
/********************************
指定时分秒的地址,并把每个变化的时间送入对应地址
********************************/
void write_sfm(uchar add,uchar sfm)
{
uchar shiw,gew;
shiw=sfm/10;//把时/分/秒,拆成十位和各位分别送入对应地址
gew=sfm%10;
write_com(0x80+0x40+add);//指向对应地址
write_data(0x30+shiw);
write_data(0x30+gew);
}
/********************************
键盘扫描,被主函数调用,调年月日
********************************/
void keyscan()
{
if(s1==0)//按下s1键,不按下(s1=1)就跳去判断s2有没有被按下
delay(5);//延时消抖
if(s1==0)//再次确定s1有没有被按下
{ s1num++;//每按一下s1键slnum就加1
while(!s1);//s1为1时(既松开s1键),执行下一条语句
TR0=0;//关闭计数器T0
if(s1num==1)//第一次按下s1键,停止计时
{
TR0=0;//关闭计数器T0
write_com(0x80+0x40+10);
write_com(0x0f);
}
if(s1num==2)//第二次按下s1键
{
write_com(0x80+0x40+7);
}
if(s1num==3)//第三次按下s1键
{
write_com(0x80+0x40+4);
}
if(s1num==4)//第四次按下s1键,并恢复计时
{
TR0=1;
s1num=0;
write_com(0x0c);
}
}
if(s1==1)//确认s1没按下
{
if(s2==0)//按下s2键
delay(5);//延时消抖
if(s2==0)//再次确定s2有没有被按下
{
while(!s2);//s2为1时(既松开s2键),执行下一条语句
if(s1num==1)//秒,每按一次秒就加一
miao++;
if(miao==60)
miao=0;
write_sfm(10,miao);
write_com(0x80+0x40+10);
if(s1num==2)//分,每按一次分就加一
{
fen++;
if(fen==60)
fen=0;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)//时,每按一次时就加一
{
shi++;
if(shi==24)
shi=0;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}
}
if(s1==1)//确认s1没按下
{
if(s3==0)//按下s2键
delay(5);//延时消抖
if(s3==0)//再次确定s2有没有被按下
{
while(!s3);//s2为1时(既松开s2键),执行下一条语句
if(s1num==1)//秒,每按一次秒就加一
miao--;
if(miao==-1)
miao=59;
write_sfm(10,miao);
write_com(0x80+0x40+10);
if(s1num==2)//分,每按一次分就加一
{
fen--;
if(fen==-1)
fen=59;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)//时,每按一次时就加一
{
shi--;
if(shi==-1)
shi=23;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}
}
}
/********************************
主函数
*******************************/
void main()
{
init();//调用初始化函数
while(1)
{
keyscan();//键盘扫描
if(t==1)//时间开始走动,先是秒,再是分,后是时
{
t=0;//t清零
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
ri++;
t1=t1+3;//星期
if(t1<22)
{
if(t1==21)
t1=0;
write_com(0x80+0x0d);
write_data(table2[t1]);
write_data(table2[t1+1]);
write_data(table2[t1+2]);
}
//日
if((nian%400==0)||(nian%100!=0)&&(nian%4==0))//判断闰年
{//是闰年
if(ri==table3[yue-1]+1)
{
ri=1;
yue++;
if(yue==13)
{
yue=1;
nian++;
}
write_nian(nian);
}
write_ry(0x07,yue);
}//
else//不是闰年
{//
if(ri==table4[yue-1]+1)
{
ri=1;
yue++;
if(yue==13)
{
yue=1;
nian++;
}
write_nian(nian);
}
write_ry(0x07,yue);
}
write_ry(0x0a,ri);
}
write_sfm(4,shi);
}
write_sfm(7,fen);
}
write_sfm(10,miao);//把变化的时间写入LCD
}
}
}
/********************************
中断程序
********************************/
void time0() interrupt 1 using 2
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
t++;
}
这是电子钟的程序(包括年月日,星期,十分秒,其中时分秒可以调节),有很多不完善的地方,希望 各位高手指出,不胜感激。该程序用到液晶显示模块RT-1602C
系统分类:
单片机 | 用户分类:
个人成长 | 来源:
原创 | 【推荐给朋友】 | 【添加到收藏夹】