找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8799|回复: 7
打印 上一主题 下一主题
收起左侧

DS1302加备用电池,掉电走时问题

[复制链接]
跳转到指定楼层
楼主
DS1302实时时钟,加了调时功能 ,仿真 实物都通过,现在想加一个掉电走时的功能,试了好多方法都不行,
把1302初始化‘init_1302(); ’这句注释掉,再把程序烧进去,掉电虽然不会初始化时间,但1302不会继续走时,时间就
停在掉电那个时候的时间,在上电只能接着掉电那个时候的时间走时

/*********************************************************************************
DS1302实时时钟,加了调时功能 ,仿真 实物都通过
**********************************************************************************/
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int

//#define W P0                                                                          //位选
//#define D P0                                                                        //段选

/*sbit IO=P1^1;                                                                          //数据口
sbit SCLK=P1^0;                                                                         //控制数据时钟
sbit RST=P1^2;                                                                          //使能端、复位端   */
                                                                                                                                  

sbit sclk = P1^0;
sbit dio = P1^1;
sbit ce = P1^2;
sbit wela = P2^7;
sbit dula = P2^6;



sbit s1=P3^0;                                                                        //按键 加
sbit s2=P3^1;                                                                        //按键 减
sbit s3=P3^3;                                                                        //按键 选择
bit flag;//是否读取时间的标志位

char knum=0,snum,fnum;

char shi,fen,miao;

bit miao_flag;
uchar miao_num,ss;


/***********写时分秒地址************/
#define write_shi  0x84
#define write_fen  0x82
#define write_miao 0x80
/***********读时分秒地址************/
#define read_shi  0x85
#define read_fen  0x83
#define read_miao 0x81
uchar d[]={ 0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F};                //共阴不带小数点

uchar dd[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef
                                };//        共阴带小数点

//uchar dd[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};                //共阳带小数点

//uchar d[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xd8,0x80,0x90};                //共阳不带小数点
//uchar dd[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};                //共阳带小数点         */

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

/*uchar code table[]={

                0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F,  //"9"
                0x77,  //"A"
                0x7C,  //"B"
                0x39,  //"C"
                0x5E,  //"D"
                0x79,  //"E"
                0x71,  //"F"
                0x76,  //"H"
                0x38,  //"L"
                0x37,  //"n"
                0x3E,  //"u"
                0x73,  //"P"
                0x5C,  //"o"
                0x40,  //"-"
                0x00,  //熄灭
                0x00  //自定义

                         };
void display(uchar shi10,shi,fen10,fen,miao10,miao)
{
        dula=1;
        P0=table[shi10];
        dula=0;
        P0=0xff;
        wela=1;
        P0=0xfe;
        wela=0;
        delay(1);

        dula=1;
        P0=table[shi]|0x80;         //         table[shi]|0x80, table[shi]或0x80就可以显示小数点
        dula=0;
        P0=0xff;
        wela=1;
        P0=0xfd;
        wela=0;
        delay(1);

        dula=1;
        P0=table[fen10];
        dula=0;
        P0=0xff;
        wela=1;
        P0=0xfb;
        wela=0;
        delay(1);

        dula=1;
        P0=table[fen]|0x80;
        dula=0;
        P0=0xff;
        wela=1;
        P0=0xf7;
        wela=0;
        delay(1);

        dula=1;
        P0=table[miao10];
        dula=0;
        P0=0xff;
        wela=1;
        P0=0xef;
        wela=0;
        delay(1);

        dula=1;
        P0=table[miao];
        dula=0;
        P0=0xff;
        wela=1;
        P0=0xdf;
        wela=0;
        delay(1);
}  */                  


void t0_init()  //定时50ms一个中断
{

  TMOD=0X01;
  TH0=(65536-45872)/256;
  TL0=(65536-45872)%256;
  EA=1;
  ET0=1;
  TR0=1;

}

void temer1() interrupt 1
{
  TH0=(65536-45872)/256;
  TL0=(65536-45872)%256;
  ss++;
  if(ss==20)
  ss=0;

}

void display(uchar shi,uchar fen,uchar miao)                          //显示函数
{
        //        if(miao%2==0)
                if(ss<=10)                 //        这里写为ss<=10,第三位数码管显示“— ”闪烁与 第六位数码管显示“= ”
                {                                  //闪烁相反,一个亮时,另一个灭
            wela=1;
                P0=0xfb;
                wela=0;

                dula=1;
        //        P0=0x40;          //第三位数码管显示“— ”
               
                P0=0x09;          //第三位数码管显示“= ”
                dula=0;
                P0=0xff;
                delay(1);
       
                }

                else
                {
                wela=1;
                P0=0xfb;
                wela=0;

                dula=1;
                P0=0;          //第三位数码管不显示
                dula=0;
                P0=0xff;
                delay(1);       
                }
       
        //        if(miao%2==0)         //if(miao%2==0) 1秒闪烁1次
                if(ss>=10)                 //if(ss>=10)闪烁频率可调
                {
                wela=1;
                P0=0xdf;
                wela=0;
                dula=1;
                P0=0x40;          //第六位数码管显示“— ”
                dula=0;
                P0=0xff;

                delay(1);
                }

                else
                {
                wela=1;
                P0=0xdf;
                wela=0;
                dula=1;
                P0=0;          //第六位数码管不显示
                dula=0;
                P0=0xff;

                delay(1);
                }
       
       
        if(knum==0)
        {
                snum=30;
                fnum=30;
        }
       
        if(knum==1)
        {
                fnum++;
                snum=30;
        }
       
        if(knum==2)
        {
                snum++;
                fnum=30;
        }
       
       
        if(snum>=30)
        {       
                if((shi/10)<1)         //如果小时十位小于1,
                {
                wela=1;
                P0=0xfe;
                wela=0;

                dula = 1;
                P0=0xff;           // 小时十位就不显示
                dula = 0;
                }
               
                else
                {
                wela=1;
                P0=0xfe;
                wela=0;

                dula=1;
                P0=d[shi/10];
                dula=0;
                P0=0xff;
                delay(1);
                }
          
         /*  if(miao%2==0)                                                        //小数点闪烁
                {
                        wela=1;
                        P0=0xfd;
                        wela=0;

                        dula=1;
                        P0=d[shi%10];                 //时的个位,P0=d[shi%10]时的个位小数点不亮
                        dula=0;                                 //时的个位,P0=dd[shi%10]时的个位小数点亮
                        P0=0xff;
                        delay(1);
                       
                       
                }  */
               
        //        else
        //        {
                        wela=1;
                        P0=0xfd;
                        wela=0;

                        dula=1;
                        P0=d[shi%10];                        //时的个位,P0=d[shi%10]时的个位小数点闪烁
                        dula=0;                                        // 时的个位,P0=dd[shi%10]时的个位小数点不闪烁
                        P0=0xff;
                        delay(1);
               
                       
        //        }
            
               
       
       
                if(snum==60)
                        snum=0;
        }               
       
       
        if(fnum>=30)
        {
                wela=1;
                P0=0xf7;
                wela=0;

                dula=1;
                P0=d[fen/10];
                dula=0;
                P0=0xff;
                delay(1);
               
               
                wela=1;
                P0=0xef;
                wela=0;

                dula=1;
                P0=d[fen%10];
                dula=0;
                P0=0xff;
                delay(1);
       
               
                if(fnum==60)
                        fnum=0;
        }
                wela=1;
                P0=0xbf;
                wela=0;

            dula=1;
                P0=d[miao/10];                           //秒十位
                dula=0;
                P0=0xff;
                delay(1);
       

                wela=1;
                P0=0x7f;
                wela=0;

                dula=1;
                P0=d[miao%10];                         //秒个位
                dula=0;
                P0=0xff;
                delay(1);
       
               
       
       
}  



void write_1302(uchar add,dat)                 //写函数  qx
{
        uchar i,temp;
        temp=add;
        ce=0;
        _nop_();
        sclk=0;
        _nop_();
        ce=1;
        _nop_();
        for(i=0;i<8;i++)
        {
                sclk=0;
                _nop_();
                if((temp&0x01)==0x01)
                        dio=1;
                        else
                        dio=0;
                temp>>=1;
                sclk=1;
                _nop_();
        }
        temp=dat;
        for(i=0;i<8;i++)
        {
                sclk=0;
                _nop_();
                if((temp&0x01)==0x01)
                        dio=1;
                        else
                        dio=0;
                temp>>=1;
                sclk=1;
                _nop_();
        }
        ce=0;
        sclk=0;
}
uchar read_1302(uchar add)                                   //读函数                qx
{
        uchar dat,dat1,i,temp;
        temp=add;
        ce=0;
        _nop_();
        sclk=0;
        _nop_();
        ce=1;
        for(i=0;i<8;i++)
        {
                sclk=0;
                _nop_();
                if((temp&0x01)==0x01)
                        dio=1;
                        else
                        dio=0;
                temp>>=1;
                sclk=1;
                _nop_();
        }
        for(i=0;i<8;i++)
        {
                sclk=0;
                _nop_();
                if(dio)
                    dat|=0x80;
                if(i<7)
                        dat>>=1;
                sclk=1;
        }
        dat1=dat/16;
        dat=dat%16;
        dat=dat1*10+dat;  
        ce=0;
        sclk=0;
        return dat;
}                                 

void init_1302()                                                        //初始化函数 设置时间
{
        write_1302(0x8e,0x00);                                        //保护取消,可以进行读写操作
        write_1302(write_miao,0x57);       
        write_1302(write_fen,0x55);
        write_1302(write_shi,0x15);
        write_1302(0x8e,0x80);                                        //保护启动,不能进行读写操作
}         

void read_sf()
{
        shi=read_1302(read_shi);
        fen=read_1302(read_fen);
        miao=read_1302(read_miao);
        display(shi,fen,miao);
}

void keyscan()                                                                   //按键扫描函数
{                                                                                  
        if(s3==0)                                                                   //选择按键按下
        {
                delay(10);                                                        //延时
                if(s3==0)
                {
                        while(!s3)                                                //松手检测
                                display(shi,fen,miao);        //加上这句,按键按下就不会闪
                        knum++;
                        if(knum==1)                                                  //分闪烁
                        {
                                 write_1302(0x8e,0x00);                //保护取消
                                 write_1302(write_miao,0x80); //  write_1302(write_miao,0x80);
                       
                        }
                       
                       
                        if(knum==3)                                                   //时钟启动
                        {
                                knum=0;
                                write_1302(write_miao,0x00);
                                write_1302(0x8e,0x80);                //保护启动
                        }
                }
        }


        if(knum==1)                                                                //分钟调节
        {
                if(s1==0)                                                        //加
                {
                        delay(10);
                        if(s1==0)
                        {       
                                while(!s1)
                                        display(shi,fen,miao);        //加上这句,按键按下就不会闪
                                fen++;
                                fen=fen/10*16+fen%10;                //转为16进制
                                if(fen==0x60)
                                        fen=0x00;
                                write_1302(write_fen,fen);        //写入1302
                                read_sf();                                        //读出时间,然后显示
                               
                               
                       
                        }
                  
                }
               
                if(s2==0)
                {
                        delay(10);
                        if(s2==0)
                        {       
                                while(!s2)
                                        display(shi,fen,miao);        //加上这句,按键按下就不会闪
                                fen--;
                                fen=fen/10*16+fen%10;                //转为16进制
                                if(fen==-1)
                                        fen=0x59;
                                write_1302(write_fen,fen);
                                read_sf();
                        }
                }

                       
        }
       
       
        if(knum==2)
        {
                if(s1==0)
                {
                        delay(10);
                        if(s1==0)
                        {       
                                while(!s1)
                                        display(shi,fen,miao);        //加上这句,按键按下就不会闪
                                shi++;
                                shi=shi/10*16+shi%10;                //转为16进制
                                if(shi==0x24)
                                        shi=0x00;
                                write_1302(write_shi,shi);
                                read_sf();
                        }
                }
                if(s2==0)
                {
                        delay(10);
                        if(s2==0)
                        {       
                                while(!s2)
                                          display(shi,fen,miao);        //加上这句,按键按下就不会闪
                                shi--;
                                shi=shi/10*16+shi%10;                //转为16进制
                                if(shi==-1)
                                        shi=0x23;
                                write_1302(write_shi,shi);
                                read_sf();
                        }
                }
        }
}




void main()
{
        t0_init();
        init_1302();
        while(1)
        {
          
            read_sf();
            
            keyscan();
                write_1302(0x8e,0x00);

                shi=read_1302(0x85);
               
                fen=read_1302(0x83);
               
                miao=read_1302(0x81);       
                write_1302(0x8e,0x00);
               
                display(shi,fen,miao);

       
                }
       
       
}



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:140489 发表于 2017-1-19 15:57 | 只看该作者
这是仿真图,事物和仿真一样的接法
回复

使用道具 举报

板凳
ID:58628 发表于 2017-1-19 16:04 来自手机 | 只看该作者
你直接用电池串二极管加在vcc2上不就可以吗
回复

使用道具 举报

地板
ID:140489 发表于 2017-1-19 16:13 | 只看该作者
abc123194 发表于 2017-1-19 16:04
你直接用电池串二极管加在vcc2上不就可以吗

直接用电池串二极管加在vcc2上,功耗较大,电池不耐用
回复

使用道具 举报

5#
ID:58628 发表于 2017-1-19 16:21 来自手机 | 只看该作者
嗯,在1302vcc供电侧也串二极管
回复

使用道具 举报

6#
ID:58628 发表于 2017-1-19 16:23 来自手机 | 只看该作者
abc123194 发表于 2017-1-19 16:21
嗯,在1302vcc供电侧也串二极管

或串2个二极管,电池侧不串二极管,平时可以给电池充电,电池应该用充电电池
回复

使用道具 举报

7#
ID:162439 发表于 2017-1-19 16:48 | 只看该作者
好复杂呀,要好好学习
回复

使用道具 举报

8#
ID:170318 发表于 2018-5-21 22:21 | 只看该作者
DS1302初始化有问题
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表