时钟程序,显示的问题,有图求真相
时钟能正常走,就是有两个数字跟问号交替出现
下面是程序:
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]=" 20 - - ";
uchar code table1[]=" : : ";
sbit lcdrs=P2^0; //1602信号
sbit lcdrw=P2^1; //写命令,置低电平
sbit lcden=P2^2; //1602使能端
sbit dsrst=P2^5; //ds1302复位
sbit dsio=P2^6; //1302IO口
sbit dssck=P2^7; //1302时钟
sbit fmq=P3^5; //蜂鸣器
sbit s0=P3^0; //增大键
sbit s1=P3^1; //减小键
sbit s2=P3^2; //功能键
sbit s3=P3^3; //闹钟查看键
bit run;
uchar miao, fen, shi, week, day, month, year, tflag;
void delayms(uint z)
{
uint x, y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void di()
{//蜂鸣器
fmq=0;
delayms(100);
fmq=1;
}
void write_com(uchar com)
{
lcdrs=0;
P0=com;
delayms(5);
lcden=1;
delayms(5);
lcden=0;
}
void write_data(uchar dat)
{
lcdrs=1;
P0=dat;
delayms(5);
lcden=1;
delayms(5);
lcden=0;
}
void write_sfm(uchar add,uchar date)
{//1602刷新时间
uchar shi,ge;
shi=date/16;
ge=date%16;
write_com(0x80+0x40+add);
write_data(0x30+shi);
write_data(0x30+ge);
}
void write_nyr(uchar add,uchar date)
{//1602刷新年月日
uchar shi,ge;
shi=date/16;
ge=date%16;
write_com(0x80+add);
write_data(0x30+shi);//0x30对应ASCII码
write_data(0x30+ge);
}
void write_week(char we)
{//星期
write_com(0x80+12);
switch(we)
{
case 1: write_data('M');delayms(5);
write_data('O');delayms(5);
write_data('N');delayms(5);
break;
case 2: write_data('T');delayms(5);
write_data('U');delayms(5);
write_data('E');delayms(5);
break;
case 3: write_data('W');delayms(5);
write_data('E');delayms(5);
write_data('D');delayms(5);
break;
case 4: write_data('T');delayms(5);
write_data('H');delayms(5);
write_data('U');delayms(5);
break;
case 5: write_data('F');delayms(5);
write_data('R');delayms(5);
write_data('T');delayms(5);
break;
case 6: write_data('S');delayms(5);
write_data('A');delayms(5);
write_data('T');delayms(5);
break;
case 7: write_data('S');delayms(5);
write_data('U');delayms(5);
write_data('N');delayms(5);
break;
}
}
void init1()
{
uchar num;
/*..液晶初始程序....*/
lcdrw=0;
lcden=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
for(num=0;num<16;num++)
write_data(table[num]);
write_com(0x80+0x40);
for(num=0;num<16;num++)
write_data(table1[num]);
/*.....*/
}
void delayus(uint t)
{
t--;
}
/*..1302读写程序.....*/
void write_byte(uchar dat)
{
uchar i;
dssck=0;//初始时钟线为0
for(i=0;i<8;i++)//开始传送八位字节的数据
{
dssck=0;
dsio=dat&0x01;//取最低位传送给IO
delayus(2);
dssck=1;//时钟线拉高,数据传走
delayus(2);
dssck=0;
dat>>=1;//右移一位
}
}
void write_ds(uchar add, uchar dat)
{
dsrst=0;//CE线为0
dssck=0;//时钟线为0
dsrst=1;//CE线为1,传输开始。位传输
write_byte(add);//传入命令字,写入时间,日历地址
write_byte(dat);//写入要修改的时间日历
dssck=1;//时钟线拉高
dsrst=0;//读取结束
}
uchar read_byte()
{
uchar i, dat;
delayus(2);
for(i=0;i<8;i++)
{
dssck=0;
dat>>=1;//左移一位
if(dsio)
dat|=0x80;//按位或,最高位成为1
delayus(2);
dssck=1;
delayus(2);
dssck=0;
}
return dat;//返回读取的值
}
uchar read_ds(uchar add)
{
uchar dat;
dsrst=0;
dssck=0;
dsrst=1;
write_byte(add);//写入命令字,地址
dat=read_byte();//读取数据
delayus(2);
dssck=1;
delayus(2);
dsrst=0;
return dat;
}
/*.....*/
/*void init2()//1302 初始化
{
write_ds(0x8e,0x00);//写保护关
write_ds(0x80,0x11);
write_ds(0x82,0x11);
write_ds(0x84,0x11);
write_ds(0x86,0x11);//日11
write_ds(0x88,0x11);//月11
write_ds(0x8a,0x05);//星期5
write_ds(0x8c,0x11);//年11
write_ds(0x90,0x01);//充电?
write_ds(0xc0,0xf0);
write_ds(0x8e,0x80);//写保护开
}*/
void main()
{
TMOD=0X02; //设置定时器0为工作方式2
TH0=0X06; //装初值
TL0=0X06;
EA=1; //开总中断
ET0=1; //开定时器0中断
TR0=1; //启动定时器0
init1(); //1602初始程序
// init2(); //1302初始程序
/* year=read_ds(0x8d);
write_nyr(3,year);
month=read_ds(0x89);
write_nyr(6,month);
day=read_ds(0x87);
write_nyr(9,day);
shi=read_ds(0x85);
write_sfm(4,shi);
fen=read_ds(0x83);
write_sfm(7,fen);
miao=read_ds(0x81);
write_sfm(10,miao);
week=read_ds(0x8b);
write_week(week);
*/
while(1)
{
delayms(20);
miao=read_ds(0x81);
fen=read_ds(0x83);
shi=read_ds(0x85);
year=read_ds(0x8d);
month=read_ds(0x89);
day=read_ds(0x87);
week=read_ds(0x8b);
write_sfm(10,miao);
write_sfm(7,fen);
write_sfm(4,shi);
write_nyr(3,year);
write_nyr(6,month);
write_nyr(9,day);
write_week(week);
}
}
void timer02()interrupt 1
{
/* tflag++;
if(tflag==4000)
{
run=1;
tflag=0;
}
*/
}