新手求助,下面的实时时钟程序哪里错了啊,怎么显示的不对,大神速来

2019-07-15 15:17发布

#include<reg52.h>
#include<intrins.h>// 包括‘空’ 操作
#define uchar unsigned char
#define uint unsigned int
sbit SCLK=P1^1;
sbit IO=P1^2;
sbit RST=P1^3;

#define ds1302_sec_add                        0x80// 定义秒数据地址
#define ds1302_min_add                        0x82
#define ds1302_hour_add                        0x84
#define ds1302_day_add                        0x86
#define ds1302_month_add                0x88
#define ds1302_week_add                        0x8a
#define ds1302_year_add                        0x8c
#define ds1302_control_add                0x8e
#define ds1302_charger_add                0x90

extern uchar time_buf1[8];// 空年月日时分秒周
extern uchar time_buf[8];// 空
/************************************************************
                        向DS1302写入一个数据
************************************************************/
//void Ds1302_Write_Byte(uchar add,uchar d);
/************************************************************
                        从DS1302读出一个数据
************************************************************/
//uchar Ds1302_Read_Byte(uchar add);
/***********************************************************
                        向DS1302写入时钟数据(初始化时间日期)
************************************************************/
//void Ds1302_Write_Time(void);
/************************************************************
                        从DS1302读出时钟数据
************************************************************/
//void Ds1302_Read_Time(void);
/************************************************************
                        DS1302初始化
************************************************************/
//void Ds1302_Init(void);

/*********************************************************************/
uchar time_buf1[8]={20,15,12,26,13,22,2,6};//年月日时分秒周
uchar time_buf[8];
/*******************************************************
                向DS1302写入一个字节数据
********************************************************/
void Ds1302_Write_Byte(uchar addr,uchar d)
{
        uchar i;
//        SCLK=0;
//        RST=0;
        RST=1;// 传输开始
        // 写入地址
        addr=addr&0xfe;// 最低位置零 ,RD=1.WE=0,故为写入状态
        for(i=0;i<8;i++)
        {
                if(addr&0x01)
                        IO=1;
                else
                        IO=0;
                SCLK=1;
                SCLK=0;
                addr=addr>>1;
        }
        //写入数据
        for(i=0;i<8;i++)
        {
                if(d&0x01)
                        IO=1;
                else
                        IO=0;
                SCLK=1;
                SCLK=0;
                d=d>>1;
        }
        RST=0;// 停止DS1302总线
}
/*************************************************
                从DS1302读出一个字节的数据
*************************************************/
uchar Ds1302_Read_Byte(uchar addr)
{
        uchar i,temp;
        RST=1;
        // 写入地址
        addr=addr|0x01;// 最低位置为1,RD=1读,WR=0写,故选取高电平
        for(i=0;i<8;i++)
        {
                if(addr&0x01)
                        IO=1;
                else
                        IO=0;
                SCLK=1;
                SCLK=0;
                addr=addr>>1;
        }
        //读数据
        for(i=0;i<8;i++)
        {
                temp=temp>>1; // 最高位置为0
                if(IO)                  // 如果此时IO口高电平,则temp最高位1
                        temp|=0x80;
                else
                        temp&=0x7f;//否则temp最高位0 ,,7次右移之后变成最低位
                SCLK=1;
                SCLK=0;
        }
        RST=0;// 停止总线
        return temp;
}

/*************************************************
                向DS1302写入时钟数据 初始化时间日期
*************************************************/
void Ds1302_Write_Time(void)
{
        uchar i,tmp;
        for(i=0;i<8;i++)
        {
                tmp=time_buf1[i]/10;                          //BCD处理,得到压缩的BCD码,4位二进制表示1位十进制数
                time_buf[i]=time_buf1[i]%10;          //初始化时采用16进制数,可不用BCD处理???(待定)
                time_buf[i]=time_buf[i]+tmp*16;
        }
        Ds1302_Write_Byte(ds1302_control_add,0x00);                        //关闭写保护
        Ds1302_Write_Byte(ds1302_sec_add,0x80);                                //暂停
//        Ds1302_Write_Byte(ds1302_charge_add,0xa9);                        //涓流充电
        Ds1302_Write_Byte(ds1302_year_add,time_buf[1]);                //年
        Ds1302_Write_Byte(ds1302_month_add,time_buf[2]);
        Ds1302_Write_Byte(ds1302_day_add,time_buf[3]);
        Ds1302_Write_Byte(ds1302_week_add,time_buf[7]);
        Ds1302_Write_Byte(ds1302_hour_add,time_buf[4]);
        Ds1302_Write_Byte(ds1302_min_add,time_buf[5]);
        Ds1302_Write_Byte(ds1302_sec_add,time_buf[6]);
        Ds1302_Write_Byte(ds1302_week_add,time_buf[7]);
        Ds1302_Write_Byte(ds1302_control_add,0x80);                         //打开写保护
}
/*******************************************************************
                        从DS1302读出时钟数据
********************************************************************/
void Ds1302_Read_Time(void)
{
        uchar i,tmp;                                                       
        time_buf[1]=Ds1302_Read_Byte(ds1302_year_add);
        time_buf[2]=Ds1302_Read_Byte(ds1302_month_add);
        time_buf[3]=Ds1302_Read_Byte(ds1302_day_add);
        time_buf[4]=Ds1302_Read_Byte(ds1302_hour_add);
        time_buf[5]=Ds1302_Read_Byte(ds1302_min_add);
        time_buf[6]=(Ds1302_Read_Byte(ds1302_sec_add))&0x7f;
        time_buf[7]=Ds1302_Read_Byte(ds1302_week_add);

        for(i=0;i<8;i++)
        {
                //BCD处理
                tmp=time_buf[i]/16;
                time_buf1[i]=time_buf[i]%16;
                time_buf1[i]=time_buf1[i]+tmp*10;
        }
}

/****************************************************
                DS1302初始化
*****************************************************/
void Ds1302_Init(void)
{
        RST=0;
        SCLK=0;
        Ds1302_Write_Byte(ds1302_sec_add,0x00);
}

/********************************************************
                        数码管显示时钟
        内容:DS1302实时时钟数码管显示,时间和日期切换显示,按下按键,循环切换
                  时间格式xx-xx-xx
                  日期格式xx-xx-xx
                  周秒格式-x-   xx
*********************************************************/
// #include<reg52.h>
#define Key P3                //定义按键端口
#define Data P0                //定义数据端口

sbit du=P2^1;
sbit we=P2^2;

bit ReadTimeFlag;        //定义读时间标志

uchar code table_du[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar code table_we[]=(0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f);
uchar TempData[8];// 存储显示值的全局变量

void delay(uint z);
void display(uchar FirstBit,uchar Num);
uchar KeyScan(void);
void Init_Timer0(void);
/************************************
                主函数
*************************************/
void main(void)
{
        uchar num,displaynum;

        Init_Timer0();
        Ds1302_Init();
        Ds1302_Write_Time();
        while(1)
        {
                num=KeyScan();
                if(num==1)
                {
                        displaynum++;
                        if(displaynum==3)
                                displaynum=0;
                }
                if(ReadTimeFlag==1)
                {
                        ReadTimeFlag=0;
                        Ds1302_Read_Time();
                        if(displaynum==0)        //显示时间
                        {
                                TempData[0]=table_du[time_buf1[4]/10]; //时
                                TempData[1]=table_du[time_buf1[4]%10];
                                TempData[2]=0x40;
                                TempData[3]=table_du[time_buf1[5]/10]; //分
                                TempData[4]=table_du[time_buf1[5]%10];
                                TempData[5]=0x40;
                                TempData[6]=table_du[time_buf1[6]/10]; //秒
                                TempData[7]=table_du[time_buf1[6]%10];
                        }
                        else if(displaynum==1)// 显示日期
                        {
                                TempData[0]=table_du[time_buf1[1]/10];//年
                                TempData[1]=table_du[time_buf1[1]%10];
                                TempData[2]=0x40;
                                TempData[3]=table_du[time_buf1[2]/10];//月
                                TempData[4]=table_du[time_buf1[2]%10];
                                TempData[5]=0x40;
                                TempData[6]=table_du[time_buf1[3]/10];//日
                                TempData[7]=table_du[time_buf1[3]%10];
                        }
                        else if(displaynum==2)// 显示周秒
                        {
                                TempData[0]=0x40;
                                TempData[1]=table_du[time_buf1[7]%10];
                                TempData[2]=0x40;
                                TempData[3]=0;
                                TempData[4]=0;
                                TempData[5]=0;
                                TempData[6]=table_du[time_buf1[6]/10];
                                TempData[7]=table_du[time_buf1[6]%10];
                        }
                }
        }
}

void delay(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}

void Display(uchar FirstBit,uchar Num)
{
        static unsigned char p=0;

        Data=0;   //消影
        du=1;
        du=0;

        Data=table_we[p+FirstBit];
        we=1;
        we=0;

        Data=TempData[p];
        du=1;
        du=0;

        p++;
        if(p==Num)
                p=0;
}
/*************************************
        定时器初始化子程序
*************************************/
void Init_Timer0(void)
{
        TMOD|=0x01;                //使用模式1,16位定时器,使用“|”符号可以在使用多个定时器时不受影响
        //TH0=(65536-50000)/256;
//        TL0=(65536-50000)%256;
        EA=1;
        ET0=1;
        TR0=1;
}

/**********************************************
                定时器中断子程序
*******************************************/
void Timer0(void) interrupt 1
{
        static unsigned int num;
        TH0=(65536-2000)/256;
        TL0=(65536-2000)%256;

        Display(0,8);//调用数码管显示,第1位开始显示,共8位
        num++;
        if(num==50)
        {
                num=0;
                ReadTimeFlag=1;
        }
}

/*******************************************
                按键扫描函数,返回扫描键值
******************************************/
uchar KeyScan()
{
        uchar keyvalue;
        if(Key!=0xff)
        {
                delay(10);
                if(Key!=0xff)
                {
                        keyvalue=Key;
                        while(Key!=0xff);
                        switch(keyvalue)
                        {
                                case 0xfe:return 1;break;
                                 case 0xfd:return 2;break;
                                case 0xfb:return 3;break;
                                case 0xf7:return 4;break;
                                 case 0xef:return 5;break;
                                 case 0xdf:return 6;break;
                                 case 0xbf:return 7;break;
                                 case 0x7f:return 8;break;
                                 default:return 0;break;
                        }
                }
        }
        return 0;
}

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。