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

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;
}

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
6条回答
shenjinliang
2019-07-16 02:10
#include <DS1302DS1302.h>
#include<reg52.h>
#include <syssys.h>

/**********/
void write1302(unsigned char addr,dat)
{
   unsigned char i,temp;
   CE=0;
   SCLK=0;
   CE=1;
   for(i=0;i<8;i++)  //写入地址
      {
         SCLK=0;
         temp=addr;
         if(temp&0x01==0x01)
               DIO=1;
         else
               DIO=0;
        addr>>=1;
        SCLK=1;
     }

   for(i=0;i<8;i++)  //写入数据
      {
        SCLK=0;
        temp=dat;
        if(temp&0x01==0x01)
             DIO=1;
        else
             DIO=0;
        dat>>=1;
        SCLK=1;
     }
}

unsigned char read1302(unsigned char addr)
{
   unsigned char i,temp,dat1,dat2;
   CE=0;
   SCLK=0;
   CE=1;
   for(i=8;i>0;i--)//写入读存储单元地址
      {
       SCLK =0;
       temp =addr;
       if(temp&0x01==0x01)
            DIO=1;
       else
           DIO=0;
      addr>>=1;
      SCLK=1;
     }

for(i=8;i>0;i--)//读数据
    {
       ACC_7=DIO;
       SCLK=1;
       ACC>>=1;
       SCLK=0;        //下降沿读出数据
     }
CE=0;
dat1=ACC;
dat2=dat1/16;
dat1=dat1%16;
dat1=dat1+dat2*10;
return(ACC);
}
/////////////////////////////////////
void Initial(void)
{
         write1302(write_protect,0x00);
         write1302(write_second,0x55);  //秒从55开始
             write1302(write_minute,0x59);  //分从59开始
             write1302(write_hour,0x16); //赋值0x80,为12小时计时,但低五位为计时为,所以,显示只显示低五位,小时从11开始
                 write1302(write_day,0x23);
             write1302(write_year,0x15);  //15年
             write1302(write_week,0x02);//周三
             write1302(write_month,0x12);//10月
         write1302(write_protect,0x80);
}
#ifndef __DS1302_H__
#define __DS1302_H__

#include <syssys.h>
#include <reg52.h>
#include<intrins.h>       
/************************************************************/
#define uchar unsigned char
#define uint unsigned int
#define write_second          0x80      //秒开始数存储,修改用(下同)
#define write_minute           0x82      //分开始数存储
#define write_hour              0x84      //时开始数存储,12小时计时,从0开始要写入0x80(12小时要判断上下午)。
#define read_second          0x81      //秒,显示要读这个存储器
#define read_minute           0x83      //分,显示要读这个存储器
#define read_hour              0x85       //时,显示要读这个存储器
#define write_day              0x86
#define read_day               0x87
#define write_month          0x88
#define read_month          0x89
#define write_week           0x8A
#define read_week           0x8B
#define write_year            0x8C
#define read_year            0x8D


#define write_protect 0x8E
/************************************************************/
sbit ACC_7=ACC^7;
sbit SCLK =P2^2;
sbit DIO  =P2^3;
sbit CE   =P2^1;      //protus软件中的RST脚
/********************************/
void write1302(unsigned char addr,dat);
unsigned char read1302(unsigned char addr);
void Initial(void);

#endif

void main(void)
{
       
    Lcd_Init();
        LCD_Clear(WHITE);
    BACK_COLOR=BLACK;;POINT_COLOR=WHITE;
    Initial();
    while(1)
       {
           key1scan();
            miao=read1302(read_second);
            fen=read1302(read_minute);
            shi=read1302(read_hour);
            ri=read1302(read_day);
            nian=read1302(read_year);
            yue=read1302(read_month);
            week=read1302(read_week);
                LCD_ShowString(0,0,"miao");LCD_Show2Num(40,0,miao,2);
                 LCD_ShowString(0,15,"fen");LCD_Show2Num(40,15,fen,2);
                 LCD_ShowString(0,31,"shi");LCD_Show2Num(40,31,shi,2);
                 LCD_ShowString(0,46,"ri");LCD_Show2Num(40,46,ri,2);
                 LCD_ShowString(0,61,"yue");LCD_Show2Num(40,61,yue,2);         
                 LCD_ShowString(0,81,"week");LCD_Show2Num(40,81,week,2);
                 LCD_ShowString(0,97,"nian");LCD_Show2Num(40,97,nian,2);
                }
}

一周热门 更多>