本文包含原理图、PCB、源代码、封装库、中英文PDF等资源
您需要 登录 才可以下载或查看,没有账号?注册会员
×
我在主程序中先显示几行字,然后在读取DS1302时间时,12864原来显示的几行字就没了,时间也读不出来,但用数码管显示都正常的呀,显示就换成了12864就显示不对了,哪看帮忙看看哈??
#include <reg52.h>
#include <intrins.h>
void Write_Ds1302_byte(unsigned char temp);
void Write_Ds1302( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302 ( unsigned char address );
void Read_RTC(void);//read RTC
void Set_RTC(void); //set RTC
sbit RS = P2^6;
sbit RW = P2^5;
sbit E = P2^7;
sbit PSB = P3^2; //串并口选择
unsigned char xx;
sbit SCK=P3^6; //时钟
sbit SDA=P3^4; //数据
sbit RST = P3^5;// DS1302复位
unsigned char l_tmpdate[7]={0,0,12,15,5,3,8};//秒分时日月周年08-05-15 12:00:00
unsigned char l_tmpdisplay[8];
code unsigned char write_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //秒分时日月周年 最低位读写位
code unsigned char read_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
//延时子程序
void delay(unsigned int t)
{ unsigned int i,j;
for(i=0;i<t;i++)
for(j=0;j<10;j++)
;
}
//测忙
void chk_busy()
{ RS=0;
RW=1;
E=1;
while((P0&0x80)==0x80);//1000 0000
E=0;
}
//读数据
unsigned char lcdrd()
{ unsigned char i;
P0=0xff;
_nop_();
E=1;
delay(5);
i=P0;
_nop_();
E=0;
return i;
}
//写数据
void lcdwd(unsigned char dispdata)
{ chk_busy();
_nop_();
RS=1;
RW=0;
E=1;
P0=dispdata;
delay(5);
_nop_();
E=0;
_nop_();
P0=0xff;
}
//写指令代码
void lcdwc(unsigned char cmdcode)
{ chk_busy();
_nop_();
RS=0;
RW=0;
E=1;
P0=cmdcode;
delay(5);
_nop_();
E=0;
_nop_();
P0=0xff;
}
//初始化
void lcdreset()
{ delay(2000);
lcdwc(0x30); //选择基本指令集0011 0000
lcdwc(0x30); //选择8bit数据流
delay(5);
lcdwc(0x0c); //开显示(无游标、不反白)0000 1100
delay(5);
lcdwc(0x01); //清除显示,并且设定地址指针为00H
delay(5);
lcdwc(0x06); //指定在资料的读取及写入时,设定游标的移动方向及指定显示的移位
}
void hzkdis(unsigned char code *s)//显示汉字用
{ while(*s>0)
{ lcdwd(*s);
s++;
delay(100);
}
}
void hzklib()
{ lcdwc(0x80+0);
hzkdis("单片机学习12864");
lcdwc(0x90+0);
hzkdis("2010年08月11日");
lcdwc(0x88+1);
hzkdis("现在时间是:");
}
//整屏显示
//当ii=0时显示上面128×32
//当ii=8时显示下面128×32
void lcdfill(unsigned char disdata)
{ unsigned char x,y,ii=0;
for(ii=0;ii<9;ii+=8)
for(y=0;y<32;y++)
for(x=0;x<8;x++)
{ lcdwc(0x36);
lcdwc(y+0x80); //行地址y
lcdwc(x+0x80+ii); //列地址x
lcdwc(0x30);
lcdwd(disdata);
lcdwd(disdata);
//delay(5000);
}
}
/******************************************************************/
/* 写一个字节 */
/******************************************************************/
void Write_Ds1302_Byte(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++) //循环8次 写入数据
{
SCK=0;
SDA=temp&0x01; //每次传输低字节
temp>>=1; //右移一位
SCK=1;
}
}
/******************************************************************/
/* 写入DS1302 */
/******************************************************************/
void Write_Ds1302( unsigned char address,unsigned char dat )
{
RST=0;
_nop_();
SCK=0;
_nop_();
RST=1;
_nop_(); //启动
Write_Ds1302_Byte(address); //发送地址
Write_Ds1302_Byte(dat); //发送数据
RST=0; //恢复
}
/******************************************************************/
/* 读出DS1302数据 */
/******************************************************************/
unsigned char Read_Ds1302 ( unsigned char address )
{
unsigned char i,temp=0x00;
RST=0;
_nop_();
_nop_();
SCK=0;
_nop_();
_nop_();
RST=1;
_nop_();
_nop_();
Write_Ds1302_Byte(address);
for (i=0;i<8;i++) //循环8次 读取数据
{
if(SDA)
temp|=0x80; //每次传输低字节
SCK=0;
temp>>=1; //右移一位
_nop_();
_nop_();
_nop_();
SCK=1;
}
RST=0;
_nop_(); //以下为DS1302复位的稳定时间
_nop_();
RST=0;
SCK=0;
_nop_();
_nop_();
_nop_();
_nop_();
SCK=1;
_nop_();
_nop_();
SDA=0;
_nop_();
_nop_();
SDA=1;
_nop_();
_nop_();
return (temp); //返回
}
/******************************************************************/
/* 读时钟数据 */
/******************************************************************/
void Read_RTC(void) //读取 日历
{
unsigned char i,*p;
p=read_rtc_address; //地址传递
for(i=0;i<7;i++) //分7次读取 秒分时日月周年
{
l_tmpdate[i]=Read_Ds1302(*p);
p++;
}
}
/******************************************************************/
/* 设定时钟数据 */
/******************************************************************/
void Set_RTC(void) //设定 日历
{
unsigned char i,*p,tmp;
for(i=0;i<7;i++){ //BCD处理
tmp=l_tmpdate[i]/10;
l_tmpdate[i]=l_tmpdate[i]%10;
l_tmpdate[i]=l_tmpdate[i]+tmp*16;
}
Write_Ds1302(0x8E,0X00);
p=write_rtc_address; //传地址
for(i=0;i<7;i++) //7次写入 秒分时日月周年
{
Write_Ds1302(*p,l_tmpdate[i]);
p++;
}
Write_Ds1302(0x8E,0x80);
}
//---------------------------------------------------------------------
main()
{
PSB=1;
RW=0;
lcdreset(); //初始化LCD屏
lcdwc(0x01); //清除显示,并且设定地址指针为00H
delay(500);
lcdfill(0xff);
delay(500);
lcdfill(0);
hzklib(); //显示汉字
while(1)
{
xx++;
if(xx==4)
{
xx=0;
l_tmpdate[0]=Read_Ds1302(0x81);
Read_RTC();
l_tmpdisplay[0]=l_tmpdate[2]/16; //数据的转换,因我们采用数码管0~9的显示,将数据分开
l_tmpdisplay[1]=l_tmpdate[2]&0x0f;
l_tmpdisplay[3]=l_tmpdate[1]/16;
l_tmpdisplay[4]=l_tmpdate[1]&0x0f;
l_tmpdisplay[6]=l_tmpdate[0]/16;
l_tmpdisplay[7]=l_tmpdate[0]&0x0f;
lcdwc(0x98+0);
lcdwd(l_tmpdisplay[0]+0x30);
//lcdwd(l_tmpdisplay[1]+0x30);
hzkdis(":");
lcdwd(l_tmpdisplay[3]+0x30);
lcdwd(l_tmpdisplay[4]+0x30);
hzkdis(":");
lcdwd(l_tmpdisplay[6]+0x30);
lcdwd(l_tmpdisplay[7]+0x30);
}
delay(1000);
}
} |
|