请大神详解DS1302程序

2020-01-30 13:32发布

*********************************包含头文件********************************/
#include "reg51.h"
#include <intrins.h>

/*********************************端口定义**********************************/
sbit DS1302_CLK = P1^0;
sbit DS1302_IO  = P1^1;
sbit DS1302_RST = P1^2;

/*******************************共阳LED段码表*******************************/
unsigned char code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

/******************************定义全局变量*********************************/
unsigned char second,minute,hour,week,day,month,year;                //秒、分、时、星期、日、月、年
unsigned char time[]={0x06,0x03,0x14,0x03,0x12,0x30,0x00};        //初始时间数组
/****************************************************************************
函数功能:数码管扫描延时子程序
入口参数:
出口参数:
****************************************************************************/
void delay1(void)
{
        int k;
        for(k=0;k<400;k++);
}

/****************************************************************************
函数功能:数码管显示子程序
入口参数:k
出口参数:
****************************************************************************/
void display(void)
{
        P2=0xfe;                       
        P0=tab[hour/16];
        delay1();

        P2=0xfd;
        P0=tab[hour%16];
        delay1();

        P2=0xfb;
        P0=0xbf;                        //显示"-"
        delay1();

        P2=0xf7;
        P0=tab[minute/16];
        delay1();

        P2=0xef;
        P0=tab[minute%16];
        delay1();

        P2=0xdf;
        P0=0xbf;                        //显示"-"
        delay1();

        P2=0xbf;
        P0=tab[second/16];
        delay1();

        P2=0x7f;
        P0=tab[second%16];
        delay1();
}

/*****************************************************************************
函数功能:向DS1302送一字节数据子程序
入口参数:
出口参数:
*****************************************************************************/
void InputByte(unsigned char byte1)
{
        char i;
        for(i=8;i>0;i--)
        {
                DS1302_IO=(bit)(byte1&0x01);
                DS1302_CLK=1;
                _nop_();
                DS1302_CLK=0;
                byte1>>=1;
        }
        return;
}

/*****************************************************************************
函数功能:读DS1302一个字节子程序
入口参数:
出口参数:
*****************************************************************************/
unsigned char outputbyte(void)  
{
        unsigned char i;
        unsigned ucdat=0;
        for(i=8;i>0;i--)
        {
                DS1302_IO=1;
                ucdat>>=1;
                if(DS1302_IO)ucdat|=0x80;
                DS1302_CLK=1;
                _nop_();
                DS1302_CLK=0;
         }
         return(ucdat);
}

/*****************************************************************************
函数功能:向DS1302某地址写一字节数据子程序
入口参数:addr,TDat
出口参数:
*****************************************************************************/
void write_ds1302(unsigned char addr,unsigned char TDat)
{
        DS1302_RST=0;
        _nop_();
        DS1302_CLK=0;
        _nop_();
        DS1302_RST=1;
        InputByte(addr);
        _nop_();
        InputByte(TDat);
        DS1302_CLK=1;
        _nop_();
        DS1302_RST=0;
}

/*****************************************************************************
函数功能:读DS1302地址子程序
入口参数:add
出口参数:timedata
*****************************************************************************/
unsigned char read_ds1302(unsigned char addr)
{
        unsigned char timedata;
        DS1302_RST=0;
        _nop_();
        DS1302_CLK=0;
        _nop_();
        DS1302_RST=1;
        InputByte(addr);
        timedata=OutputByte();
        DS1302_CLK=1;
        _nop_();
        DS1302_RST=0;
        return(timedata);
}

/*****************************************************************************
函数功能:初始化DS1302子程序
入口参数:time[](全局变量)
出口参数:
*****************************************************************************/
void initial_ds1302()
{
        write_ds1302(0x8e,0x00);                //写保护寄存器,在对时钟或RAM写前WP一定要为0
        write_ds1302(0x8c,time[0]);                //年
        write_ds1302(0x88,time[1]);                //月
        write_ds1302(0x86,time[2]);                //日
        write_ds1302(0x8A,time[3]);                //星期
        write_ds1302(0x84,time[4]);                //时
        write_ds1302(0x82,time[5]);                //分
        write_ds1302(0x80,time[6]);                //秒
        write_ds1302(0x8e,0x80);                //写保护寄存器
}

/*****************************************************************************
函数功能:读DS1302时间子程序
入口参数:
出口参数:全局变量(second,minute,hour,week,day,month,year)
*****************************************************************************/
void read_time()
{
        second=read_ds1302(0x81);                //秒寄存器
        minute=read_ds1302(0x83);                //分
        hour=read_ds1302(0x85);                        //时
        week=read_ds1302(0x8B);                        //星期
        day=read_ds1302(0x87);                        //日
        month=read_ds1302(0x89);                //月
        year=read_ds1302(0x8d);                        //年
}

/*****************************************************************************
函数功能:主程序
入口参数:
出口参数:
*****************************************************************************/
void main(void)
{
        initial_ds1302();                                //初始化DS1302
        while(1)
        {
                read_time();                                //读取时间
                display();                                        //显示时间
        }
}

请大神们详细讲解下这三段代码的工作原理,谢谢谢谢!!!!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
10条回答
millwood0
1楼-- · 2020-01-30 14:00
 精彩回答 2  元偷偷看……
jcrorxp
2楼-- · 2020-01-30 19:43
1,  对DS1302的寄存器进行配置, 就是说你要马儿跑 先要告诉马儿 你要用慢跑还是快跑,你要向前跑还是倒着跑,  这里主要是告诉DS1302 现在的时间,还有日期 还有12 24 小时等等.

2,  这里作用是 驱动数码管 P1应该接的是数码管,具体要看看你的电路.   

P0=tab[hour/16];  P0=tab[hour%16];

是显示个位与10位   比如   hour = 12   则 第一条公式=0  第二条公式=12
                              如果  hour=  19                第一条=1       第二条=3;

如果这还理解不了, 请看C语言的基础书.

第三断代码  应该是服务于第一段代码的,  也就是说  你要跟马儿交流  必须用特点的交流方式,

这里 IN BYTE   OUT BYTE     就是分别 向 DS1302 写入     问DS1302 读取,  一个字节,

这就是所谓的时序了,  要看芯片手册.  

sunliezhi
3楼-- · 2020-01-30 21:21
        P2=0xfe;                       
        P0=tab[hour/16];
        delay1();

        P2=0xfd;
        P0=tab[hour%16];
        delay1();

        P2=0xfb;
        P0=0xbf;                        //显示"-"
        delay1();

        P2=0xf7;
        P0=tab[minute/16];
        delay1();

        P2=0xef;
        P0=tab[minute%16];
        delay1();

        P2=0xdf;
        P0=0xbf;                        //显示"-"
        delay1();

        P2=0xbf;
        P0=tab[second/16];
        delay1();

        P2=0x7f;
        P0=tab[second%16];
        delay1();
P2口8条IO分时选通(低电平有效)某位LED数码管,总共8位数码管;
P0是数据输出口;
你告诉大家你看过DS1302的datasheet没有? 对DS1302了解多少? 这样大家才好帮你。
gongxd
4楼-- · 2020-01-31 02:15
看手册 看时序图
Making
5楼-- · 2020-01-31 04:18
手册 上面都有啊。
jamasliu
6楼-- · 2020-01-31 04:27
 精彩回答 2  元偷偷看……

一周热门 更多>