我写的PCF8563程序不知道哪里出错了,请高手帮帮忙看一下错在哪里谢拉

2020-01-17 19:04发布

/******************************************************
时钟模块
时钟由FPC8563产生,程序如下:
作者:sjx  2008-7-27    QQ:307870154
*********************************************************/
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit scl1=P2^0;//定义数码管时钟线
sbit sda1=P2^1;//定义数码管数据线
sbit scl3=P2^4;//定义数码管时钟线
sbit sda3=P2^5;//定义数码管数据线
sbit scl4=P2^6;//定义数码管时钟线
sbit sda4=P2^7;//定义数码管数据线
sbit scl=P0^6;//定义8563 I2C的时钟线       
sbit sda=P0^7; //定义8563 I2C的数据线
uchar a,miao,shi,fen,number, b;
uint  day,week,month,year;
uchar code  tab[]={0x11,0x7d,0x23,0x29,0x4d,                         // 0 1 2 3 4 //
                0x89,0x81,0x3d,0x01,0x09,          // 5 6 7 8 9 //
                0x05,0xc1,0x93,0x61,0x83,0x87        }; // A B C D E F
void delay()
{ ;; }
//=========8563起始信号子程序===============
void start()  
{       
   
        sda=1;
        delay();
        scl=1;
        delay();
        sda=0;
        delay();
}
//==========8563终止信号子程序================
void stop()
{
        sda=0;
        delay();
        scl=1;
        delay();
        sda=1;
        delay();
}
//===========8563应答信号子程序====================
void respons()
{
        uchar i;
        scl=1;
        delay();
        while((sda==1)&&(i<250))i++;  //若无应答,重新开始发送地址
        scl=0;
        delay();
}
//===========8563总线初始化子程序=======================
void init()
{
        sda=1;
        delay();
        scl=1;
        delay();
}
//===========写入1字节子程序======================

void write_byte(uchar date)
{
        uchar i,temp;
        temp=date;          //写入数据date


        for(i=0;i<8;i++)
        {
                temp=temp<<1;
                scl=0;
            delay();
                sda=CY;         //往数据线送date最高位,循环8次送完date
                delay();
                scl=1;
                delay();
                scl=0;
        delay();
        }
        sda=1;         //释放数据总线,以便读取应答信号
        delay();
}
//===========读取1字节子程序============================
uchar read_byte()
{
        uchar i,k;
        scl=0;
        delay();
        sda=1;
        delay();
        for(i=0;i<8;i++) //读回时是一位一位的所以要读8次
        {
                scl=1;          // scl置1数据才稳定才可以读取数据
                delay();       
                k=(k<<1)|sda;         //sda送过来的数据送到k的最底位,循环8次从最高位读完sda上的数据
                scl=0;
                delay();       
        }
        return k;        //程序执行完返回k的值
}
//============延时子程序=====================================
void delay1(uchar x)
{
        uchar a,b;
        for(a=x;a>0;a--)
         for(b=100;b>0;b--);
}
//===========写一8位数据子程序===================================
void write_add(uchar address,uchar date)  
{                                         
        start();  //调用起始信号子程序,开始写入信号            
        write_byte(0xa2); //找芯片所在地址
        respons();                  //调用应答信号
        write_byte(address);//找芯片内部存储器地址
        respons();
        write_byte(date);//        写入数据,写进芯片内部存储器
        respons();
        stop();                         //调用终止信号子程序,终止信号写入
}
//===========读一8位数据子程序 ================================
uchar read_add(uchar address)
{
        uchar date;
        start();         //调用起始信号子程序
        write_byte(0xa2);  //取芯片地址
        respons();
        write_byte(address);//取芯片内部存储器地址
        respons();
        start();          //调用起始信号子程序,开始读取信号
        write_byte(0xa3);//芯片读地址
        respons();
        date=read_byte();//把读取字节子程序的返回值给date
        stop();
        return date;   // 程序执行完返回date的值
}
//===============写时间子程序=============
void write_8563(uchar w_miao,uchar w_fen,uchar w_shi,uchar w_day,uchar w_week,uchar w_month,uchar w_year)
{   init();
    start();
        write_add(0x00,0x00);
   write_add(0x01,0x00);
   write_add(0x02, w_miao);
   delay1(100);
   write_add(0x03,w_fen);
   delay1(100);
   write_add(0x4,w_shi);
   delay1(100);
   write_add(0x05,w_day);
   delay1(100);
   write_add(0x06,w_week);
   delay1(100);
   write_add(0x7,w_month);
   delay1(100);
   write_add(0x8,w_year);
   delay1(100);
   
}

//===============读时间子程序============
   void read_8563()
   {   
       miao=read_add(0x02)&0x7f;//获取秒数据       
       miao=((miao&0xf0)>>4&0x0f)*10+(miao&0x0f);//BCD码转换成10进制数
           if(miao>=60){miao=0;}
          

           fen=read_add(0x03)&0x7f;//获取分钟
           fen=((fen&0xf0)>>4&0x0f)*10+(fen&0x0f);//BCD码转换成10进制数
           if(fen>=60){fen=0;}
      

           shi=read_add(0x04)&0x3f;//获取小时
           shi=((shi&0xf0)>>4&0x0f)*10+(shi&0x0f);//BCD码转换成10进制数
           if(shi>=24){shi=0;}
          

           day=read_add(0x05)&0x3f;//获取日数据       
        day=(( day&0xf0)>>4&0x0f)*10+( day&0x0f);//BCD码转换成10进制数
           if( day>=31){ day=0;}
          

           week=read_add(0x06)&0x07;//获取星期
           if(week>6){week=0;}
      
           month=read_add(0x07)&0x1f;//获取月
           month=((month&0xf0)>>4&0x0f)*10+(month&0x0f);//BCD码转换成10进制数
           if(month>=24){month=0;}
          
           year=read_add(0x08)&0xff;//获取年
           shi=((year&0xf0)>>4&0x0f)*10+(year&0x0f);//BCD码转换成10进制数
           delay1(100);
   }
/********************************************************
********************************************************/
//============数码管移位子程序===================
void  shift1()
{
   uchar i,t;
   number=tab;
   scl1=0;
   for(i=0;i<8;i++)
    {
      t=number&0x80; //与、判断,0 1, 0x80为二进制数10000000
      sda1=t;                 //        往数据线送最高位
      scl1=1;                 //上跳
      number=number<<1;         //左移一位
      scl1=0;                         //下跳
     }
}

void  shift3()
{
   uchar i,t;
   number=tab;
   scl3=0;
   for(i=0;i<8;i++)
    {
      t=number&0x80; //与、判断,0 1, 0x80为二进制数10000000
      sda3=t;                 //        往数据线送最高位
      scl3=1;                 //上跳
      number=number<<1;         //左移一位
      scl3=0;                         //下跳
     }
}

void  shift4()
{
   uchar i,t;
   number=tab;
   scl4=0;
   for(i=0;i<8;i++)
    {
      t=number&0x80; //与、判断,0 1, 0x80为二进制数10000000
      sda4=t;                 //        往数据线送最高位
      scl4=1;                 //上跳
      number=number<<1;         //左移一位
      scl4=0;                         //下跳
     }
}
//============数码管显示程序========================
void  dispaly()
{       
      b=miao%10;//秒个位
          shift3();
          b=miao/10;//秒十位
          shift3();
          b=fen%10;
          shift4();
          b=fen/10;
          shift4();
          b=shi%10;
          shift4();
          b=shi/10;
          shift4();

          b=week%10;//秒个位
          shift1();
         
          b=day%10;
          shift1();
          b=day/10;
          shift1();
          b=month%10;
          shift1();
          b=month/10;
          shift1();
          b=year%10; //年个位
          shift1();
          b=(year%100)/10;//年十位
          shift1();
          b=(year%1000)/100;//年百位
          shift1();
          b=year/1000;
          shift1();
          delay1(500);

}
//===========主程序=======================================================
void main()
{
        init();
        delay1(500);                  
        write_8563(0x50,0x59,0x23,0x11,0x01,0x09,0x2008);//初始化秒 分 时,日,星期,月,年
        delay1(500);      //调用延时函数
    while(1)
    {       
    read_8563();  //读取秒 时 分
        dispaly();         //显示秒 分 时
        }
   
}
此程序显示读取年和小时那里出错了。单独读取时 分 秒是没有错 但是同时读取年月日星期时分秒时,读不出小时。而且年的千位也是一直读不出请高手帮忙改正谢拉
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。