jamasliu 发表于 2013-5-21 00:42:56

请大神详解DS1302程序

*********************************包含头文件********************************/
#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;
        delay1();

        P2=0xfd;
        P0=tab;
        delay1();

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

        P2=0xf7;
        P0=tab;
        delay1();

        P2=0xef;
        P0=tab;
        delay1();

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

        P2=0xbf;
        P0=tab;
        delay1();

        P2=0x7f;
        P0=tab;
        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);                //年
        write_ds1302(0x88,time);                //月
        write_ds1302(0x86,time);                //日
        write_ds1302(0x8A,time);                //星期
        write_ds1302(0x84,time);                //时
        write_ds1302(0x82,time);                //分
        write_ds1302(0x80,time);                //秒
        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();                                        //显示时间
        }
}

请大神们详细讲解下这三段代码的工作原理,谢谢谢谢!!!!

millwood0 发表于 2013-5-21 02:23:26

请大神详解DS1302程序

Easy:

1) understand how your code works: your code is organized fairly logically - everything is built on InputByte() (moronic name, btw) and outputbyte(), and layered from there onward.
2) take out the datasheet for ds1302 and compare the timing chart to see how InputByte() and outputbyte() work.
3) from there, understanding how write_ds1302() and read_ds1302() work and other routines ...

jcrorxp 发表于 2013-5-21 08:09:47

1,对DS1302的寄存器进行配置, 就是说你要马儿跑 先要告诉马儿 你要用慢跑还是快跑,你要向前跑还是倒着跑,这里主要是告诉DS1302 现在的时间,还有日期 还有12 24 小时等等.

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

P0=tab;P0=tab;

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

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

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

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

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

sunliezhi 发表于 2013-5-21 08:47:17

      P2=0xfe;                     
      P0=tab;
      delay1();

      P2=0xfd;
      P0=tab;
      delay1();

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

      P2=0xf7;
      P0=tab;
      delay1();

      P2=0xef;
      P0=tab;
      delay1();

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

      P2=0xbf;
      P0=tab;
      delay1();

      P2=0x7f;
      P0=tab;
      delay1();
P2口8条IO分时选通(低电平有效)某位LED数码管,总共8位数码管;
P0是数据输出口;
你告诉大家你看过DS1302的datasheet没有? 对DS1302了解多少? 这样大家才好帮你。

gongxd 发表于 2013-5-21 08:52:56

看手册 看时序图

Making 发表于 2013-5-21 09:04:19

手册 上面都有啊。{:lol:}

jamasliu 发表于 2013-5-21 09:25:30

看了,就是没有看懂,初始化代码中,年:time中的值是怎么转换的,谢谢大家的回复。。

bbssilverkey 发表于 2013-5-21 09:49:12

本帖最后由 bbssilverkey 于 2013-5-21 09:51 编辑

简答说说:QQ图片20130521091905.jpg

bbssilverkey 发表于 2013-5-21 09:51:06

单字节读:CE拉高,IO调好,拉高时钟线就送出去啦{:titter:}

duanll 发表于 2013-5-21 10:39:59

简单点就是:

比如,分钟10,送进去的不是0x0a,而是0x10,同理,11分钟,送进去的是0x11

cdlxzlp 发表于 2013-5-21 20:40:08

好 东西了啊哈哈
页: [1]
查看完整版本: 请大神详解DS1302程序