#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit rs=P3^0; //液晶12864的接口
sbit rw=P3^1;
sbit en=P3^2;
sbit clk=P2^4; //1302时钟线
sbit date=P2^5; //1302数据线
sbit rst=P2^6;//1302复位线
uint shi,fen,miao,nian,yue,ri,xingqi;
uchar shijian[8];//用来储存读回来的时间
void delay_ms(uint x) //液晶延时子程序 (ms)
{
uint i,j;
for(j=0;j<x;j++)
for(i=0;i<110;i++);
}
void delay_us(uint n) //延时(us),当n=1,为20us,当=2,为30us
{
uint i;
for(i=0;i<n;i++);
}
void write_cmd(uint cmd) //液晶的写指令
{
rs=0;
rw=0;
en=0;
P0=cmd;
delay_ms(5);
en=1;
delay_ms(5);
en=0;
}
void write_dat(uint dat) //液晶的写数据
{
rs=1;
rw=0;
en=0;
P0=dat;
delay_ms(5);
en=1;
delay_ms(5);
en=0;
}
void pos(uchar x,uchar y) //确定液晶写指令的位置
{
uchar pos;
if(x==0)
{x=0x80;}
else if(x==1)
{x=0x90;}
else if(x==2)
{x=0x88;}
else if(x==3)
{x=0x98;}
pos=x+y;
write_cmd(pos);
}
void init_lcd() //初始化液晶
{
write_cmd(0x06);
write_cmd(0x0c); //开显示,关光标
write_cmd(0x30); //基本指令操作
write_cmd(0x01); //清屏
}
void print(uchar *str) //显示字符串
{
while(*str!='\0')
{
write_dat(*str);
str++;
}
}
void write_1302(uint dat) //往1302中写入一个字节
{
uint i;
rst=1;
clk=0;
for(i=0;i>8;i++)
{
date=dat&0x01;
delay_us(2);
clk=1;
delay_us(2);
clk=0;
dat>>=1;
}
rst=0;
}
void w_1302(uint cmd,uint dat) //往1302中写控制字、数据
{
rst=0;
clk=0;
rst=1;
delay_us(2);
write_1302(cmd);
write_1302(dat);
clk=1;
rst=0;
}
uchar read_1302() //从1302中读一个字节
{
uint i=0,dat=0;
delay_us(2);
for(i=0;i<8;i++)
{
dat>>=1;
if(date==1)
dat|=0x80;
clk=1;
delay_us(2);
clk=0;
delay_us(2);
}
return dat;
}
uchar r_1302(uint cmd) //从1302中根据控制字读数据
{
uchar dat;
rst=0; //拉低RST
clk=0; //确保写数居前SCLK被拉低
rst=1; //启动数据传输
write_1302(cmd); //写入命令字
dat=read_1302(); //读出数据
clk=1; //将时钟电平置于已知状态
rst=0; //禁止数据传递
return dat; //将读出的数据返回
}
init_1302()
{
uchar flag;
flag=r_1302(0x81);
if(flag&0x80)
{ //判断时钟芯片是否关闭 如果内部关的话就初始化,没有关的话就继续走
w_1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令
w_1302(0x80,((55/10)<<4|(55%10))); //根据写秒寄存器命令字,写入秒的初始值
w_1302(0x82,((59/10)<<4|(59%10))); //根据写分寄存器命令字,写入分的初始值
w_1302(0x84,((23/10)<<4|(23%10))); //根据写小时寄存器命令字,写入小时的初始值
w_1302(0x86,((18/10)<<4|(18%10))); //根据写日寄存器命令字,写入日的初始值
w_1302(0x88,((6/10)<<4|(6%10))); //根据写月寄存器命令字,写入月的初始值
w_1302(0x8c,((9/10)<<4|(9%10))); //根据写年寄存器命令字,写入年的初始值
w_1302(0x90,0xa5); //打开充电功能 选择2K电阻充电方式
w_1302(0x8E,0x80); //根据写状态寄存器命令字,写入保护指令
}
}
void display_1302(uint shi,uint fen,uint miao) //把数据分离,存到数组shijian里
{
uchar shishi,shige,fenshi,fenge,miaoshi,miaoge;
shishi=shi/10;
shige=shi%10;
fenshi=fen/10;
fenge=fen%10;
miaoshi=miao/10;
miaoge=miao%10;
shijian[0]=shishi;
shijian[1]=shige;
shijian[2]=':';
shijian[3]=fenshi;
shijian[4]=fenge;
shijian[5]=':';
shijian[6]=miaoshi;
shijian[7]=miaoge;
}
void get_1302() //从1302里读取值并转换
{
uint hour,minute,second;
hour=r_1302(0x85);
shi=((hour&0x70)>>4)*10 + (hour&0x0F);
minute=r_1302(0x83);
fen=((minute&0x70)>>4)*10 + (minute&0x0F);
second=r_1302(0x81);
miao=((second&0x70)>>4)*10 + (second&0x0F);
display_1302(shi,fen,miao);
}
void show() //显示子函数
{
get_1302();
pos(2,4);
print(shijian);
delay_ms(500);
}
void main()
{
init_lcd();
init_1302();
while(1)
{
show();
}
}
各位大侠帮忙看看哪里出了问题,12864上显示不正确,小弟菜鸟正在学习中、谢各位了、、、、 |