1302和1602显示出乱码,并且时钟不走
时间:10-02
整理:3721RD
点击:

#include<reg52.h>
#include<clock.h>
#include<delay.h>
void write_com(uchar com) //液晶写指令函数
{
rs=0;
lcden=0;
P0=com; //给数据口赋值
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_date(uchar date)
{
rs=1;
lcden=0;
P0=date; //给数据口赋值
delay(5);
lcden=1;
delay(5);
lcden=0;
}
/*********************************************/
/* 初始化LCD1602 */
/*********************************************/
void init_1602()
{
uchar num;
write_com(0x38); //写指令,开显示
write_com(0x0c); //显示开及光标设置
write_com(0x06); //光标显示,并左移
write_com(0x01); //清屏,清零
write_com(0x80+1); //从第一行开始写
for(num=0;num<9;num++)
{
write_date(table[num]);
delay(5);
}
write_com(0x80+0x40+4); //第二行开始写
for(num=0;num<6;num++)
{
write_date(table1[num]);
delay(5);
}
}
void init() //初始化函数
{
EA=1; //打开总中断
EX1=1; //打开外部中断
IT1=1; //设置为负跳变沿触发
//beep=1; //蜂鸣器不响
//flag1=0; //控制闹铃
}
/*********************************************/
/* 1302写一个字节 */
/*********************************************/
void Write_1302(uchar temp) //1302写数据
{
uchar i;
SCLK=0;//初始时钟线置为0
for(i=0;i<8;i++)//连续写8个二进制位数据
{
SDA=temp&0x01;//取最低位,注意 DS1302的数据和地址都是从最低位开始传输的
delay(1);
SCLK=1; //时钟线拉高,制造上升沿,SDA的数据被传输
delay(1);
SCLK=0;//时钟线拉低,为下一个上升沿做准备
temp>>=1;//将dat的各数据位右移1位,准备写入下一个数据位
}
}
/*********************************************/
/* 写入DS1302 */
/*********************************************/
void WriteSet_1302(uchar address,uchar dat)
{
RST=0;//禁止数据传递
SCLK=0;//确保写数居前SCLK被拉低
RST=1;//启动数据传输
delay(1);
Write_1302(address); //发送地址
Write_1302(dat); //发送数据
SCLK=1; //时钟线拉高
RST=0;//禁止数据传递,恢复
}
/*********************************************/
/* 1302读一个字节 */
/*********************************************/
uchar Read_1302()
{
uchar i,temp;
delay(2);
for(i=0;i<8;i++)
{
temp>>=1;//要返回的数据左移一位
if(SDA==1)//当数据线为高时,证明该位数据为 1
temp|=0x80;//要传输数据的当前值置为 1,若不是,则为 0
SCLK=1;//拉高时钟线
delay(2);
SCLK=0;//制造下降沿
delay(2);
}
return temp;//返回读取出的数据
}
/*********************************************/
/* 读出DS1302数据 */
/*********************************************/
uchar ReadSet_1302(uchar address)
{
uchar temp;
RST=0;//拉低RST
SCLK=0;//确保写数居前SCLK被拉低
RST=1;//启动数据传输
Write_1302(address);//写入命令字
temp=Read_1302();//读取要得到的时间/日期
SCLK=1;//时钟线拉高
RST=0;//读取结束,CE置为 0,结束数据的传输
return temp;//返回得到的时间/日期
}
/*********************************************/
/* 读时钟数据 */
/*********************************************/
void Read_RTC(void)//读取 日历
{
uchar i,*p;
p=read_rtc_address;//地址传递
for(i=0;i<7;i++)//分7次读取 秒分时日月年周
{
l_tmpdate=ReadSet_1302(*p);
p++;
miao=l_tmpdate[0];
fen =l_tmpdate[1];
shi =l_tmpdate[2];
ri =l_tmpdate[3];
yue =l_tmpdate[4];
nian=l_tmpdate[5];
week=l_tmpdate[6];
}
}
/*********************************************/
/* 设定时钟数据 */
/*********************************************/
void Set_RTC(void)//设定 日历
{
uchar i,*p,tmp;
for(i=0;i<7;i++)
{
//BCD处理
tmp=l_tmpdate/10;
l_tmpdate=l_tmpdate%10;
l_tmpdate=l_tmpdate+tmp*16;
}
WriteSet_1302(0x8E,0x00); //允许写,禁止写保护
p=write_rtc_address; //传地址
for(i=0;i<7;i++)//7次写入 秒分时日月年周
{
WriteSet_1302(*p,l_tmpdate);
p++;
}
WriteSet_1302(0x8E,0x80); //打开写保护
}
/*********************************************/
/* 显示时分秒 */
/*********************************************/
void write_sfm(uchar add,uchar dat)
{
uchar shi,ge;
shi=dat/16;
ge=dat%16;
write_com(0x80+0x40+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
/*********************************************/
/* 显示年月日 */
/*********************************************/
void write_nyr(uchar add,uchar dat)
{
uchar shi,ge;
shi=dat/16;
ge=dat%16;
write_com(0x80+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
/*********************************************/
/* 显示星期 */
/*********************************************/
void write_week(char dat)
{
uchar i;
dat=dat*3;
write_com(0x80+13);
for(i=0;i<3;i++)
{
write_date(table2[dat]);
dat++;
}
}
/*********************************************/
/* 显示函数 */
/*********************************************/
void display()
{
write_sfm(10,miao);
write_sfm(7,fen);
write_sfm(4,shi);
write_nyr(4,nian);
write_nyr(7,yue);
write_nyr(10,ri);
write_week(week);
}
/*********************************************/
/* 按键扫描 */
/*********************************************/
void keyscan()
{
if(flag1==1)//按任意键关闭闹铃
{
if(s2==0) //判断S2是否按下
{
delay(5);
if(s2==0) //按下S2
{
while(!s2);
flag1=0;
}
}
if(s3==0) //判断S3是否按下
{
delay(5);
if(s3==0) //按下S3
{
while(!s3);
flag1=0;
}
}
}
if(s1==0) //判断S1是否按下
{
delay(5);
if(s1==0) //S1按下
{
s1num++;
flag=1; //flag=1,时钟暂停
flag1=0;
while(!s1);
if(s1num==1) //S1按下一次
{
write_com(0x80+0x4b); //光标在秒位置
write_com(0x0f); //开显示,显示光标,光标闪烁
WriteSet_1302(0x8e,0x00); //允许写,禁止写保护
WriteSet_1302(0x80,0x80|miao);//写入DS1302秒位
WriteSet_1302(0x8e,0x80);//打开写保护
}
}
if(s1num==2) //光标在分位置
{
write_com(0x80+0x48);
}
if(s1num==3) //光标在时位置
{
write_com(0x80+0x45);
}
if(s1num==4) //光标在星期位置
{
write_com(0x80+0x0d);
}
if(s1num==5) //光标在日位置
{
write_com(0x80+0x0b);
}
if(s1num==6) //光标在月位置
{
write_com(0x80+0x08);
}
if(s1num==7) //光标在年位置
{
write_com(0x80+0x05);
}
if(s1num==8)
{
flag=0;
s1num=0;
write_com(0x0c); //显示开及光标设置
WriteSet_1302(0x8e,0x00); //允许写,禁止写保护
WriteSet_1302(0x80,0x00|miao);//写入DS1302秒位
WriteSet_1302(0x8e,0x80);//打开写保护
}
}
if(s1num!=0)//S1按下
{
if(s2==0)//判断S2是否按下
{
delay(1);
if(s2==0)//S2按下
{
while(!s2);
if(s1num==1) //S1按下1次数
{
miao++;
if(miao==60)
miao=0;
write_com(0x80+0x4b);//秒位置闪烁
WriteSet_1302(0x8e,0x00); //允许写,禁止写保护
WriteSet_1302(0x80,miao);//写入DS1302
WriteSet_1302(0x8e,0x80);//打开写保护
}
if(s1num==2) //S1按下2次数
{
fen++;
if(fen==60)
fen=0;
write_com(0x80+0x48);
WriteSet_1302(0x8e,0x00); //允许写,禁止写保护
WriteSet_1302(0x82,0x82|fen);//写入DS1302分位
WriteSet_1302(0x8e,0x80);//打开写保护
}
if(s1num==3) //S1按下3次数
{
shi++;
if(shi==24)
shi=0;
write_com(0x80+0x45);
WriteSet_1302(0x8e,0x00); //允许写,禁止写保护
WriteSet_1302(0x84,0x84|shi);//写入DS1302时位
WriteSet_1302(0x8e,0x80);//打开写保护
}
if(s1num==4) //S1按下4次数
{
week++;
if(week==8)
week=1;
write_com(0x80+0x0d);
WriteSet_1302(0x8e,0x00); //允许写,禁止写保护
WriteSet_1302(0x8a,0x8a|week);//写入DS1302周位
WriteSet_1302(0x8e,0x80);//打开写保护
}
if(s1num==5) //S1按下5次数
{
ri++;
if(ri==32)
ri=1;
write_com(0x80+0x0b);
WriteSet_1302(0x8e,0x00); //允许写,禁止写保护
WriteSet_1302(0x86,0x86|ri);//写入DS1302日位
WriteSet_1302(0x8e,0x80);//打开写保护
}
if(s1num==6) // S1按下6次数
{
yue++;
if(yue==13)
yue=1;
write_com(0x80+0x08);
WriteSet_1302(0x8e,0x00); //允许写,禁止写保护
WriteSet_1302(0x88,0x88|yue);//写入DS1302月位
WriteSet_1302(0x8e,0x80);//打开写保护
}
if(s1num==7) //S1按下7次数
{
nian++;
if(nian==100)
nian=0;
write_com(0x80+0x05);
WriteSet_1302(0x8e,0x00); //允许写,禁止写保护
WriteSet_1302(0x8c,0x8c|nian);//写入DS1302年位
WriteSet_1302(0x8e,0x80);//打开写保护
}
}
}
if(s3==0)//判断S3是否按下
{
delay(1);
if(s3==0) //S3按下
{
while(!s3);
if(s1num==1)
{
miao--;
if(miao==-1)
miao=59;
write_com(0x80+0x4b);
WriteSet_1302(0x8e,0x00); //允许写,禁止写保护
WriteSet_1302(0x80,0x80|miao);//写入DS1302秒位
WriteSet_1302(0x8e,0x80);//打开写保护
}
if(s1num==2)
{
fen--;
if(fen==-1)
fen=59;
write_com(0x80+0x48);
WriteSet_1302(0x8e,0x00); //允许写,禁止写保护
WriteSet_1302(0x82,0x82|fen);//写入DS1302分位
WriteSet_1302(0x8e,0x80);//打开写保护
}
if(s1num==3)
{
shi--;
if(shi==-1)
shi=23;
write_com(0x80+0x45);
WriteSet_1302(0x8e,0x00); //允许写,禁止写保护
WriteSet_1302(0x84,0x84|shi);//写入DS1302时位
WriteSet_1302(0x8e,0x80);//打开写保护
}
if(s1num==4)
{
week--;
if(week==0)
week=7;
write_com(0x80+0x0d);
WriteSet_1302(0x8e,0x00); //允许写,禁止写保护
WriteSet_1302(0x8a,0x8a|week);//写入DS1302周位
WriteSet_1302(0x8e,0x80);//打开写保护
}
if(s1num==5)
{
ri--;
if(ri==0)
ri=31;
write_com(0x80+0x0b);
WriteSet_1302(0x8e,0x00); //允许写,禁止写保护
WriteSet_1302(0x86,0x86|ri);//写入DS1302日位
WriteSet_1302(0x8e,0x80);//打开写保护
}
if(s1num==6)
{
yue--;
if(yue==0)
yue=12;
write_com(0x80+0x08);
WriteSet_1302(0x8e,0x00); //允许写,禁止写保护
WriteSet_1302(0x88,0x88|yue);//写入DS1302月位
WriteSet_1302(0x8e,0x80);//打开写保护
}
if(s1num==7)
{
nian--;
if(nian==-1)
nian=99;
write_com(0x80+0x05);
WriteSet_1302(0x8e,0x00); //允许写,禁止写保护
WriteSet_1302(0x8c,0x8c|nian);//写入DS1302年位
WriteSet_1302(0x8e,0x80);//打开写保护
}
}
}
}
}
void Init_DS1302(void)
{
WriteSet_1302(0x8e,0x00);//写保护关
WriteSet_1302(miao,0x00); //初始秒值为0
WriteSet_1302(fen,0x20);//初始分钟值为 0
WriteSet_1302(shi,0x09); //初始为 24小时模式 初始时间为 0点
WriteSet_1302(ri,0x25); //2011年1月1日 星期6
WriteSet_1302(yue,0x12);
WriteSet_1302(nian,0x10);
WriteSet_1302(week,0x06);
WriteSet_1302(0x90,0x01); //充电
WriteSet_1302(0xc0,0xf0); //初始化一次标示
WriteSet_1302(0x8e,0x80);
}
void main()
{
init();
init_1602();
Init_DS1302();
while(1)
{
keyscan();
//if(flag1==1)
//{
// beezzer();
//}
if(flag==0)
{
Read_RTC();
display();
}
}
}
看你的操作方式像是串行?
是串行输入的 现在可以显示了,但是秒可以走到80 分 也是可以走到80
