标题:
单片机1602智能电子钟源程序+Proteus仿真
[打印本页]
作者:
whiteM3
时间:
2019-7-30 16:14
标题:
单片机1602智能电子钟源程序+Proteus仿真
程序初始化为系统时间,显示于LCD1602,可以使用按钮修改时间,并与系统同步。
程序可能有一点点缺陷,感兴趣的朋友可以继续完善。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
QQ图片20190730160628.png
(39.81 KB, 下载次数: 89)
下载附件
智能电子钟
2019-7-30 16:09 上传
单片机源程序如下:
#include<reg51.h>
typedef unsigned char uchar;
typedef unsigned int uint;
uchar code table[]= " 2019/07/17/Tue ";
uchar code table1[]=" 12/05/10 ";
uchar code table2[]={"Tus"};
sbit RS=P2^0;
sbit RW=P2^1;
sbit E=P2^2;
sbit K1=P1^0;
sbit K2=P1^1;
sbit K3=P1^2;
sbit K4=P1^3;
sbit RST=P2^5;
sbit SCK=P2^6;
sbit IO=P2^7;
char shi,fen,miao,flag,dat,ri,yue,nian,xingqi;
void write_ds(uchar add,uchar date);
//延迟
void delay(uchar z)
{
uchar x,y;
for(x=z;x>0;x--)
for(y=10;y>0;y--);
}
//P0口写操作,先写地址,再写数据
void write_com(uchar com)
{
RS=0;
RW=0;
P0=com;
E=1;
delay(3);
E=0;
}
void write_date(uchar date)
{
RS=1;
RW=0;
P0=date;
E=1;
delay(3);
E=0;
}
//LCD显示初始化
void init_lcd()
{
uchar num;
write_com(0X38);
write_com(0X0C);
write_com(0X06);
write_com(0X80);
for(num=0;num<16;num++)
{
write_date(table[num]);
delay(5);
}
write_com(0x80+0x40);
for(num=0;num<20;num++)
{
write_date(table1[num]);
delay(5);
}
}
//LCD显示
void display1(uchar add,uchar date) //第一行显示
{
uchar temp,shi,ge;
temp=date;
shi=temp/16;
ge=temp%16;
write_com(0x80+add);
write_date(0x30+shi); //这里要注意,显示的是ASCII码!
write_date(0x30+ge);
}
void display(uchar add,uchar date) //第二行显示
{
uchar temp,shi,ge;
temp=date;
shi=temp/16;
ge=temp%16;
write_com(0x80+0x40+add);
write_date(0x30+shi); //这里要注意,显示的是ASCII码!
write_date(0x30+ge);
}
//键盘扫描
void keyscan()
{
static unsigned char num;
K1=0;
//光标移动(入口地址)
if(K2==0)
{
delay(5);
if(K2==0)
{
while(!K2);
delay(5);
while(!K2);
num++;
flag=1;
}//异常重要!!!!
if(num==1)
{
write_com(0X80+0X40+11);
write_com(0X0F);
}
if(num==2)
{
write_com(0X80+0X40+8);
write_com(0X0F);
}
if(num==3)
{
write_com(0X80+0X40+5);
write_com(0X0F);
}
if(num==4)
{
write_com(0x80+10);
write_com(0x0f);
}
if(num==5)
{
write_com(0x80+7);
write_com(0x0f);
}
if(num==6)
{
write_com(0x80+4);
write_com(0x0f);
}
if(num==7)
{
num=0;
write_com(0X0C);
write_ds(0x80,miao); //要在最后一次性写入,时分和分针定时的时候秒针还在走。
write_ds(0x82,fen);
write_ds(0x84,shi);
write_ds(0x86,ri);
write_ds(0x88,yue);
write_ds(0x8A,nian);
flag=0;
}
}
//修改时间,增加1
if(K3==0)
{
delay(5);
if(K3==0)
{
while(!K3);
delay(5);
while(!K3);
//修改秒
if(num==1)
{
uchar ge,shi;
miao++;
shi=miao/16;
ge=miao%16;
//秒的修整
if(ge>=10)
{
ge=0;
shi++;
if(shi==6){shi=0;}
}
//显示修整值
miao=shi*16+ge;
display(10,miao);
write_com(0x80+0x40+11);//把光标位置移回来。
write_ds(0x80,miao);
}
//修改分钟
if(num==2)
{
uchar ge,shi;
fen++;
shi=fen/16;
ge=fen%16;
if(ge>=10)
{
ge=0;
shi++;
if(shi==6){shi=0;}
}
fen=shi*16+ge;
display(7,fen);
write_com(0x80+0x40+8);
write_ds(0x82,fen);
}
//修改小时
if(num==3)
{
uchar ge,shi1;
shi++;
shi1=shi/16;
ge=shi%16;
if(ge>=10)
{
ge=0;
shi1++;
}
if((shi1==2)&&(ge==4))
{
shi1=0;
ge=0;
}
shi=shi1*16+ge;
display(4,shi);
write_com(0x80+0x40+5);
write_ds(0x84,shi);
}
}
}
//修改时间,减少1
if(K4==0)
{
delay(5);
if(K4==0)
{
while(!K4);
delay(5);
while(!K4);
//修改秒
if(num==1)
{
uchar ge,shi;
miao--;
shi=miao/16;
ge=miao%16;
//减法0之后应该是9,而不是“?”
if(ge==0x0f){ge=9;}
//修改时间,当到达0后,再减的话是-1
if(ge==-1)
{
shi=5;
ge=9;
}
miao=shi*16+ge;
display(10,miao);
write_com(0x80+0x40+11);
write_ds(0x80,miao);
}
//修改分钟
if(num==2)
{
uchar ge,shi;
fen--;
shi=fen/16;
ge=fen%16;
if(ge==0x0f){ge=9;}
if(ge==-1)
{
shi=5;
ge=9;
}
fen=shi*16+ge;
display(7,fen);
write_com(0x80+0x40+8);
write_ds(0x82,fen);
}
//修改小时
if(num==3)
{
uchar ge,shi1;
shi--;
shi1=shi/16;
ge=shi%16;
if(ge==0x0f){ge=9;}
if(ge==-1)
{
shi1=2;
ge=3;
}
shi=shi1*16+ge;
display(4,shi);
write_com(0x80+0x40+5);
write_ds(0x84,shi);
}
}
}
}
//DS1302
void write_ds(uchar add,uchar date)
{
uchar num;
RST=0;//复位
delay(1);
SCK=0;
delay(1);
RST=1;//关闭复位,开始传输
delay(1);
for(num=0;num<8;num++)
{
IO=add&0x01;//地址从低位开始传送
add>>=1;
//date=date<<1;
//IO=CY;
SCK=1;
delay(1);
SCK=0;
delay(1);
}
for(num=0;num<8;num++)
{
IO=date&0x01;//数据从低位开始传送
date>>=1;
//date=date<<1;
//IO=CY;
SCK=1;
delay(1);
SCK=0;
delay(1);
}
RST=0;//传输结束,复位
delay(5);
}
uchar read_ds(uchar add)
{
uchar num,temp,date;
RST=0;//复位
delay(1);
SCK=0;
delay(1);
RST=1;
delay(1);
for(num=0;num<8;num++)//先写入地址
{
IO=add&0x01;//数据从低位开始传送
add>>=1;
//date=date<<1;
//IO=CY;
SCK=1;
delay(1);
SCK=0;
delay(1);
}
delay(2);
for(num=0;num<8;num++)
{
temp=IO;
date=(date>>1)|(temp<<7);
SCK=1;
delay(1);
SCK=0;
delay(1);
}
RST=0;
delay(1);
SCK=1;
delay(1);
IO=0;
delay(1);
IO=1;
delay(1);
return date;
}
//LCD初始更新为系统时间
void init_ds()
{
miao=read_ds(0x81);
display(10,miao);
fen=read_ds(0x83);
display(7,fen);
shi=read_ds(0x85);
display(4,shi);
ri=read_ds(0x87);
display1(9,ri);
yue=read_ds(0x89);
display1(6,yue);
//xingqi=read_ds(0x8B);
//display(12,table2[]);
nian=read_ds(0x8D);
display1(3,nian);
}
void set_time()
{
write_ds(0x80,0x10);//设置初始时间秒;
write_ds(0x82,0x10);//设置初始时间分;
write_ds(0x84,0x14);//设置初始时间时;
write_ds(0x86,0x22);//设置初始时间日;
write_ds(0x88,0x03);//设置初始时间月;
write_ds(0x8a,0x03);//设置初始时间星期;
write_ds(0x8c,0x15);//设置初始时间年;
}
void main()
{
flag=0;
write_ds(0x8e,0x00);
init_lcd();
while(1)
{
keyscan();
if(flag==0){init_ds();}
}
}
复制代码
全部资料51hei下载地址:
智能电子钟.zip
(323.42 KB, 下载次数: 125)
2019-9-18 21:16 上传
点击文件名下载附件
C51
下载积分: 黑币 -5
作者:
wasd.1234
时间:
2020-11-24 11:26
P1.0按了没反应啊
作者:
xiao_hei
时间:
2020-12-2 21:14
请问为什么修改"table1[]"的数值,对应仿真显示与设置的不一样呢?但是修改table[]的就是正常的,这其中有什么奥秘吗?期待各位大佬的帮助指导。
作者:
xcv5736
时间:
2021-6-17 18:56
写的真好
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1