DS1302+LCD1602制作万年历+按键调时

2019-03-24 17:27发布

我用DS1302+LCD1602制作电子时钟,显示总出错,不知道怎么回事,求求各位大神帮帮忙
#include<reg51.h>
#include<intrins.h>
typedef unsigned char uchar;
typedef unsigned int uint;
sbit ACC7=ACC^7;//位寻址寄存器定义
sbit RS=P2^0;//LCD1602寄存器选择,高电平数据寄存器,低电平指令寄存器
sbit RW=P2^1;//读写信号线,高电平读操作,低电平写操作
sbit EN=P2^2;//DS1302使能端,由高电平跳变低电平时,执行命令
sbit SCLK=P1^1;//同步串行时钟输入引脚
sbit RST=P1^2; /*复位引脚,低电平时芯片使能,可以进行数据的读写操作,高电平时
               禁止读写操作,SCLK低电平时,才能把RST置高电平 */
sbit SDA=P1^0;//数据输入输出端
sbit K1=P3^4;        //选择
sbit K2=P3^5;        //加
sbit K3=P3^6;        //减
sbit K4=P3^7;        //时钟设置键
sbit fengming=P2^4;
bit         flag1,flag2,flag;
uchar code table1[]={"Welcom to LCD"};//code一个程序的可执行条令,程序存储区
uchar code table2[]={"Electronic Clock"};
uchar TIME[7]={30,30,9,5,11,6,16};//秒,分,时,日,月,周,年
uchar write_add[]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
uchar read_add[]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d} ;
char K1num,K2num,K3num,K4num,lshi,lfen,lmiao;
char shi,fen,miao,nian,yue,ri,week ;
void delay(uint z) //延时函数
{uchar x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void didi()        //蜂鸣器响,灯亮
{uint i;
for(i=0;i<60;i++)
{fengming=1;
delay(500);
fengming=0;
delay(500);
}
}
void write_com(uchar com)//LCD写指令
{delay(500);
RS=0; //寄存器选择,指令寄存器打开
RW=0;//低电平进行写操作
EN=0;
P0=com;//指令传给P0口
EN=1;        //使能端从高电平向低电平跳变,写指令
delay(5);
EN=0;
}
void write_data(uchar date)        //LCD写数据
{delay(500);
RS=1; //打开数据寄存器
RW=0;
EN=0;
P0=date;
delay(5);
EN=1;//使能端跳变
delay(5);
EN=0;
RS=0;
}
void init()         //LCD液晶初始化
{
RW=0;//打开写操作
EN=0;
write_com(0x38);
_nop_();
write_com(0x38);
_nop_();
write_com(0x38);
_nop_();//设置LCD显示是16*2显示,5*7点阵
write_com(0x06);//开显示,不显示光标
write_com(0x0c);//写一个字符后,地址指针加1
write_com(0x01);//清屏指令
}
void huanying()
{uchar i;
write_com(0x80);
for(i=0;i<16;i++)
write_data(table1[i]);
write_com(0x80+0x40);//将指针移向第二行
for(i=0;i<16;i++)
write_data(table2[i]);
}
void write_sfm()  //显示的时间
{write_com(0x80+0x43);
write_data(TIME[2]/10+0x30);
write_data(TIME[2]%10+0x30);
write_data(':');
write_data(TIME[1]/10+0x30);
write_data(TIME[1]%10+0X30);
write_data(':');
write_data(TIME[0]/10);
write_data(TIME[0]%10+0x30);
}
void write_nyr()
{write_com(0x80+0x01);
write_data('2');
write_data('0');
write_data(TIME[6]/10+0x30);
write_data(TIME[6]%10+0x30);
write_data('-');
write_data(TIME[4]/10+0x30);
write_data(TIME[4]%10+0x30);
write_data('-');
write_data(TIME[3]/10+0x30);
write_data(TIME[3]%10+0x30);
}
void write_week()//显示周信息
{write_com(0x80+12);
switch(TIME[1])
{
case 1: write_data('M');delay(5);
        write_data('O');delay(5);
                write_data('N');break;
case 2: write_data('T');delay(5);
        write_data('U');delay(5);
                write_data('E');break;
case 3: write_data('W');delay(5);
        write_data('E');delay(5);
                write_data('D');break;
case 4: write_data('T');delay(5);
        write_data('H');delay(5);
                write_data('U');break;
case 5: write_data('F');delay(5);
        write_data('R');delay(5);
                write_data('I');break;
case 6: write_data('S');delay(5);
        write_data('A');delay(5);
                write_data('T');break;
case 7: write_data('S');delay(5);
        write_data('U');delay(5);
                write_data('N');break;
}                                               
}
void write_byte(uchar add)
{uchar i;
for(i-0;i<8;i++)
{SCLK=0;
SDA=(bit)add&0x01;
add>>=1;
SCLK=1;
}
}
void write_1302(uchar DS_add,uchar DS_dat) //DS1302写数据
{RST=0;         //拉低RST,芯片禁止读写
_nop_();
SCLK=0;//SCLK为低电平时,才能把RST为高电平,时钟下降沿读取
_nop_();
RST=1;        //芯片开启读写
_nop_();
write_byte(DS_add);
write_byte(DS_dat);
RST=0;
_nop_();
SDA=1;
SCLK=1;
}
uchar read_1302(uchar DS_add)
{uchar i,value;
RST=0;
SCLK=0;
RST=1;
write_byte(DS_add);
for(i=0;i<8;i++)
{value>>=1;
SCLK=0;
if(SDA)
{value=value|0x80;}
SCLK=1;
}
RST=0 ;
_nop_();
SCLK=1;
_nop_();
SDA=1;
return value;
}
void set_time()
{uchar i,j,k;
for(i=0;i<7;i++)
{j=TIME[i]/10;
k=TIME[i]%10;
TIME[i]=k+j*16;         //将数组转化成BCD码
}
write_1302(0x8e,0x00);
for(i=0;i<7;i++)
{write_1302(write_add[i],TIME[i]); //将转化后的值写入芯片
}
write_1302(0x90,0x05); //充电
write_1302(0x8c,0x08); //重启
write_1302(0x8e,0x80);
}
void read_time()
{uchar i;
for(i=0;i<7;i++)
{TIME[i]=read_1302(read_add[i]);
}
}
void read_alarm()
{lfen=read_1302(3);
lshi=read_1302(5);
}
void key_scan()
{if(flag1==1)
{if((K1==0)||(K2==0)||(K3==0)||(K4==0))
{delay(5);
if((K1==0)||(K2==0)||(K3==0)||(K4==0))
{while(!(K1&&K2&&K3&&K4)) ;didi();
flag1=0;
}
}}
if(K1==0&&flag==1)
{delay(5);
if(K1==0)
{K1num++;
if(flag2==1)
if(K1num==4)
K1num=1;
while(!K1);didi();
switch(K1num)
{case 1:write_com(0x80+0x40+10);                       
        write_com(0x0f); //光标闪烁
                break;
case 2:write_com(0x80+0x40+7);
        break;
case 3:write_com(0x80+0x40+4);
                break;
case 4:write_com(0X80+12);
        break;
case 5:write_com(0x80+10);
        break;
case 6:write_com(0x80+7);
        break;
case 7:write_com(0x80+4);
        break;
case 8:K1num=0;
                write_1302(0x80,miao);
                write_1302(2,fen);
                write_1302(4,shi);
                write_1302(6,week);
                write_1302(7,ri);
                write_1302(8,yue);
                write_1302(9,nian);
                break;
}
}
}
if(K1num!=0)
{if(K2==0)
{delay(1);
if(K2==0)
{while(!K2);didi();
switch(K1num)
{case 1: miao++;
         if(miao==60)
                 miao=0;
                 write_sfm(10,miao);
                 write_com(0x80+0x40+10);
                 break;
case 2: fen++;
         if(fen==60)
                 fen=0;
                 write_sfm(7,fen);
                 write_com(0x80+0x40+7);
                 break;
case 3: shi++;
         if(shi==24)
                 shi=0;
                 write_sfm(4,shi);
                 write_com(0x80+0x40+4);
                 break;
case 4: week++;
         if(week==8)
                 week=1;
                 write_week(week);
                 write_com(0x80+12);
                 break;
case 5: ri++;
         if(ri==32)
                 ri=1;
                 write_nyr(9,ri);
                 write_com(0x80+9);
                 break;
case 6: yue++;
         if(yue==13)
                 yue=1;
                 write_nyr(6,yue);
                 write_com(0x80+6);
                 break;
case 7: nian++;
         if(nian==100)
                 nian=0;
                 write_nyr(3,nian);
                 write_com(0x80+3);
                 break;
}                                       
}
}
if(K3==0)
{delay(1);
if(K3==0)
{while(!K3);didi();
switch(K1num)
{case 1: miao--;
         if(miao==-1)
                 miao=59;
                 write_sfm(10,miao);
                 write_com(0x80+0x40+10);
                 break;
case 2: fen--;
         if(fen==-1)
                 fen=59;
                 write_sfm(7,fen);
                 write_com(0x80+0x40+7);
                 break;
case 3: shi--;
         if(shi==-1)
                 shi=23;
                 write_sfm(4,shi);
                 write_com(0x80+0x40+4);
                 break;
case 4: week--;
         if(week==0)
                 week=7;
                 write_week(week);
                 write_com(0x80+12);
                 break;
case 5: ri--;
         if(ri==0)
                 ri=31;
                 write_nyr(9,ri);
                 write_com(0x80+9);
                 break;
case 6: yue--;
                 if(yue==0)
                 yue=12;
                 write_nyr(6,yue);
                 write_com(0x80+6);
                 break;
case 7: nian--;
         if(nian==-1)
                 nian=99;
                 write_nyr(3,nian);
                 write_com(0x80+3);
                 break;
}
}
}
}
if(K4==0)
{delay(5);
if(K4==0)
{flag2=~flag2;
while(!K4); didi();
if(flag2==0)
{write_com(0x80+0x40);
write_com(0x0c);//清屏指令
write_1302(1,miao);
write_1302(3,fen);
write_1302(5,shi);}
else
{read_alarm();
fen=lfen;
shi=lshi;
write_com(0x80+0x40);
write_com(0x80+0x40+3);
write_sfm(4,lshi);
write_sfm(7,lfen);
}}}}
void main()
{init();
delay(5);
huanying();
delay(5000);
write_com(0x01);
delay(10);
set_time();
delay(5);
while(1)
{write_nyr();
delay(5);  
write_sfm();
delay(5);
write_week();
delay(5);
read_time();
if(flag==1)
{key_scan();}
if(flag1==1)
{didi();
delay(100);
didi();
delay(500)
}}
求求各位大神了,先谢过各位了

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
7条回答
zl2168
1楼-- · 2019-03-24 22:22
本帖最后由 zl2168 于 2016-11-14 22:13 编辑

实例90  开机显示PC机时间的时钟1302(LCD1602显示)


DS 1302简介

引脚功能

操作控制字

读写时序

片内寄存器

读写子程序

电路设计

程序设计

Keil调试

Proteus仿真

Proteus仿真一下,确认有效。 实例90 开机显示PC机时间的时钟1302(LCD1602显示).rar (50.36 KB, 下载次数: 71) 2016-11-14 22:12 上传 点击文件名下载附件 开机显示PC机时间的时钟1302.jpg
摘自张志良编著《80C51单片机仿真设计实例教程——基于Keil C和Proteus》清华大学出版社ISBN 978-7-302-41682-1,内有常用的单片机应用100案例,用于仿真实验操作,电路与程序真实可靠可信可行。书中电路和程序设计有详细说明,程序语句条条有注解。




zl2168
2楼-- · 2019-03-25 01:16
本帖最后由 zl2168 于 2016-11-14 22:16 编辑

实例91  具有校正功能的时钟1302(LCD1602显示)
上例时钟电路是开机显示PC机时间,无时钟校正功能,本例具有时钟校正功能。
电路设计    …
程序设计    …
Keil调试    …
Proteus仿真    …
先Proteus仿真,确认有效
实例91 带校正时钟1302(LCD1602显示).rar (52.74 KB, 下载次数: 120) 2016-11-14 22:15 上传 点击文件名下载附件
具有校正功能的时钟1302.jpg
以上摘自张志良编著《《80C51单片机仿真设计实例教程——基于Keil C和Proteus》清华大学出版社ISBN 978-7-302-41682-1,内有常用的单片机应用100案例,用于仿真实验操作,电路与程序真实可靠可信可行。
书中电路和程序设计有详细说明,程序语句条条有注解。
zl2168
3楼-- · 2019-03-25 03:28
 精彩回答 2  元偷偷看……
zl2168
4楼-- · 2019-03-25 06:09
本帖最后由 zl2168 于 2016-11-14 22:21 编辑

实例93  具有校正功能的时钟1302(LED数码管显示)
上例LED显示的1302时钟电路时钟校正功能,本例加上时钟校正功能(校正方法与实例91略有不同)。




电路设计    功能设计    程序设计    Proteus仿真   

Proteus仿真一下,确认有效。 实例93 带校正时分秒的时钟1302(6位LED数码管显示).rar (732.75 KB, 下载次数: 36) 2016-11-14 22:21 上传 点击文件名下载附件 开机显示PC机时分秒的时钟(6位LED数码管显示).jpg
以上摘自张志良编著《80C51单片机仿真设计实例教程——基于Keil CProteus》清华大学出版社ISBN 978-7-302-41682-1,内有常用的单片机应用100案例,用于仿真实验操作,电路与程序真实可靠可信可行。



暴风雪AJ
5楼-- · 2019-03-25 12:04
大哥,你有这个程序吗?能不能发一下,先谢谢您了
暴风雪AJ
6楼-- · 2019-03-25 13:05
 精彩回答 2  元偷偷看……

一周热门 更多>