编程论坛
直播中

Wtiansun

8年用户 23经验值
私信 关注
[问答]

我用LCD12864和1302做电子时钟动不了?我是用做1602时钟的方法做的,1602可以计时,12864动不了。求帮忙

#include
#include                   //右移、左移
#define uint unsigned int
#define uchar unsigned char

#define DS1302_SECOND_READ      0x81
#define DS1302_MINUTE_READ      0x83
#define DS1302_HOUR_READ        0x85
#define DS1302_DAY_READ             0x87
#define DS1302_MON_READ             0x89
#define DS1302_YEAR_READ             0x8d

#define WRITE_PROTECT           0x8e


***it rs=P2^2;//写指令/数据                            //12864
***it rw=P2^3;//读状态/写
***it e=P2^4;//使能端
***it p***=P2^5;//串/并输入


***it SCLK=P1^5;                                               //1302
***it DATA=P1^4;
***it RST=P1^6;

uchar code table1[]="20  年  月  日";
uchar code table2[]="  时  分  秒";

uchar num;
uchar day,mon,year,sec,min,hour;
void delay(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
        for(y=110;y>0;y--);          //延时
}



void check_busy()                                                                           //LCD12864程序
{
rs=0;
rw=1;
e=1;
P0=0xff;
while((P0&0x80)==0x80);
e=0;
}
//写指令
void write_com(uchar com)
{
check_busy();
rs=0;
rw=0;
e=1;
P0=com;
delay(5);
e=0;
delay(5);
}
//写数据
void write_date(uchar _date)
{
check_busy();
rs=1;
rw=0;
e=1;
P0=_date;
delay(5);
e=0;
delay(5);
}

                                                       //初始化lcd

                                                                               
                                                                                                                           //DS1302

void Write1302(uchar dat)
{
   uchar i;
   SCLK=0;               //拉低SCLK,为脉冲上升沿写入数据做好准备
   delay(5);         //稍微等待,使硬件做好准备
   for(i=0;i<8;i++)    //连续写8个二进制位数据
{
   DATA=dat&0x01;    //取出dat的第0位数据写入1302
   delay(5);     //稍微等待,使硬件做好准备
   SCLK=1;         //上升沿写入数据
   delay(5);   //稍微等待,使硬件做好准备
   SCLK=0;       //重新拉低SCLK,形成脉冲
   dat>>=1;     //将dat的各数据位右移1位,准备写入下一个数据位
}

}


void WriteSet1302(unsigned char Cmd,unsigned char dat)
{
   RST=0;                //禁止数据传递
   SCLK=0;               //确保写数据前SCLK被拉低
   RST=1;                //启动数据传输
   delay(5);          //稍微等待,使硬件做好准备
   Write1302(Cmd);      //写入命令字
   Write1302(dat);     //写数据
   SCLK=1;            //将时钟电平置于已知状态
   RST=0;            //禁止数据传递
}


unsigned char Read1302(void)
{
    uchar i,dat;         
    delay(5);;             //稍微等待,使硬件做好准备
    for(i=0;i<8;i++)        //连续读8个二进制位数据
{
    dat>>=1;               //将dat的各数据位右移1位,因为先读出的是字节的最低位
    if(DATA==1)           //如果读出的数据是1
    dat|=0x80;           //将1取出,写在dat的最高位
    SCLK=1;             //将SCLK置于高电平,为下降沿读出
    delay(5);       //稍微等待
    SCLK=0;           //拉低SCLK,形成脉冲下降沿
    delay(5);     //稍微等待
}
    return dat;     //将读出的数据返回
}


unsigned char ReadSet1302(uchar Cmd)
{
uchar dat;
RST=0;                //拉低RST
SCLK=0;              //确保写数居前SCLK被拉低
RST=1;              //启动数据传输
Write1302(Cmd);    //写入命令字
dat=Read1302();   //读出数据
SCLK=1;          //将时钟电平置于已知状态
RST=0;          //禁止数据传递
dat = dat/16*10+dat%16;          //分离十位和个位,将十六进制数转化为十进制数
return dat;    //将读出的数据返回
}

void write_sfm(uchar add,uchar date)
{
  uchar ge,shi;
  shi=date/10;
  ge=date%10;
  write_com(0+add);
  write_date(0x30+shi);
  write_date(0x30+ge);
}


void display()
{
        day=ReadSet1302(DS1302_DAY_READ);
        mon=ReadSet1302(DS1302_MON_READ);
        year=ReadSet1302(DS1302_YEAR_READ);
        sec=ReadSet1302(DS1302_SECOND_READ);
        min=ReadSet1302(DS1302_MINUTE_READ);
        hour=ReadSet1302(DS1302_HOUR_READ);
        write_sfm(0x80+5,day);
        write_sfm(0x80+3,mon);
        write_sfm(0x80+1,year);
        write_sfm(0x90+4,sec);
        write_sfm(0x90+2,min);
        write_sfm(0x90,hour);
}

void Init_DS1302()                              //DS1302初始化
{       

          WriteSet1302(0x8E,0x00);                 //根据写状态寄存器命令字,写入不保护指令
          WriteSet1302(0x8E,0x80);                           //根据写状态寄存器命令字,写入保护指令
    }

void init()                                                                                                   //LCD12864程序
{
rw=0;
p***=1;//选择为并行输入
delay(50);
write_com(0x30);//基本指令操作
delay(5);
write_com(0x0c);//显示开,关光标
delay(5);
write_com(0x06);//写入一个字符,地址加1
delay(5);
write_com(0x01);

         write_com(0x80);
        for(num=0;num<14;num++)                     \第一行显示年月日                         
{
        write_date(table1[num]);                                 
        delay(20);
}

        write_com(0x90);                                       
        for(num=0;num<12;num++)                  \第二行显示时分秒
{
        write_date(table2[num]);                       
        delay(20);
}

}


void main()
{
  init();
  Init_DS1302();
  while(1)
  {
          display();
  }

}


更多回帖

发帖
×
20
完善资料,
赚取积分