找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6822|回复: 0
收起左侧

DS1302实时时钟程序寄存器控制字及时序分析

[复制链接]
ID:72008 发表于 2015-1-11 14:36 | 显示全部楼层 |阅读模式
1、时序图
2、控制字
3、寄存器地址与RAM地址
4、代码

    时序图


控制字



寄存器与RAM



代码:
#include <reg52.h>

#include <intrins.h>

sbit dm = P2^2;        //段码
sbit wm = P2^3;        //位码

sbit st = P1^6;        //使能(RST)
sbit cl = P1^4;        //时钟管脚(CLK)
sbit da = P1^5;        //i/o管脚(数据管脚)(i/o)


/*这两个函数就这时钟芯片的精髓*/
void x_1302(unsigned char addr,unsigned char q,bit l);        //写入8个bit(参数1:地址,参数2:数据,参数3:启用BCD处理)
unsigned char d_1302(unsigned char addr,bit l);                                //读取8个bit(参数1:地址,参数2:启用BCD处理)
/*上面的两函数就是最低层的函数了*/

//下面的常量是一些寄存器的地址
#define addr_m        0x80        //秒
#define addr_f        0x82        //分
#define addr_x        0x84        //小时
#define addr_rq        0x86        //日期
#define addr_y        0x88        //月
#define addr_xq        0x8a        //星期
#define addr_n        0x8c        //年
#define addr_xbh 0x8e        //写保护
#define addr_ram 0xc0        //RAM 开始地址(这款芯片有31个8位的RAM起始地址是C0)

//下面的是一些用到的全局变量
unsigned char hc[8];        //数码管缓存
unsigned char DM[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9
unsigned char WM[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};        //位码。显示的位置
unsigned char sjhc[8]={20,13,12,12,14,30,10,4};        //空年月日时分秒周
unsigned char shijian[8];        //保存返回的数据

void DelayUs2x(unsigned char t)        //延时
{   
while(--t);
}

void x_1302(unsigned char addr,unsigned char q,bit l)        //写入8个bit(参数1:地址,参数2:数据,参数3:启用BCD处理)
{
        unsigned char i;
        if(l)        //BCD处理
        {
                i=q/10;
                q=q%10;
                q=q+i*16;
        }
        addr = addr & 0xFE;     //最低位置零
        cl = 0;        //拉低时钟
        da = 0;        //复位数据
        st = 1;        //使能芯片。写入开始
        for(i=0;i<8;i++)        //写入地址
        {
                addr >>= 1;
                da = CY;
                cl = 1;
                cl = 0;        
        }
        for(i=0;i<8;i++)        //写入数据
        {
                q >>= 1;
                da = CY;
                cl = 1;
                cl = 0;
        }
        st = 0;        //写入结束
}

unsigned char d_1302(unsigned char addr,bit l)        //读取8个bit(参数1:地址,参数2:启用BCD处理)
{
        unsigned char i,dat;
        addr = addr | 0x01;//最低位置高
        cl = 0;        //拉低时钟
        da = 0;        //复位数据
        st = 1;        //使能芯片,读取开始
        for(i=0;i<8;i++)        //写入地址
        {
                addr >>= 1;
                da = CY;
                cl = 1;
                cl = 0;
        }
        for(i=0;i<8;i++)        //读取数据
        {
                dat >>= 1;
                if(da)
                        dat = dat | 0x80;
                cl = 1;
                cl = 0;
        }
        st = 0;        //读取结束
        if(l)        //BCD处理
        {
                i = dat / 16;        
                dat = dat % 16;
                dat = dat +i*10;
        }
        return dat;
}

void d_sj()        //读出时间写入数码管缓存
{
        shijian[0]= d_1302(addr_x,0);        //读出小时BCD数据
        shijian[1]= d_1302(addr_f,0);        //读出分钟BCD数据
        shijian[2]= d_1302(addr_m,0);        //读出秒BCD数据
        hc[0]=DM[shijian[0]/16];
        hc[1]=DM[shijian[0]%16];
        hc[2]=0x40;
        hc[3]=DM[shijian[1]/16];
        hc[4]=DM[shijian[1]%16];
        hc[5]=0x40;
        hc[6]=DM[shijian[2]/16];
        hc[7]=DM[shijian[2]%16];
}

void sm()        //数码管扫描显示
{
        unsigned char i;
        for(i=0;i<8;i++)
        {
                P0 = 0;        //消影
                dm = 1;
                dm = 0;

                P0 = WM[ i];        //写入位码
                wm = 1;
                wm = 0;

                P0 = hc[ i];        //写入段码
                dm = 1;
                dm = 0;
                DelayUs2x(10);
        }
}
void x_sj()        //写入时间
{
        x_1302(addr_xbh,0,0);                //关闭写保护
        x_1302(addr_x,sjhc[4],1);        //写入小时(参数1:地址,参数2:数据,参数3:启用BCD处理)
        x_1302(addr_f,sjhc[5],1);        //写入分钟(参数1:地址,参数2:数据,参数3:启用BCD处理)
        x_1302(addr_m,sjhc[6],1);        //写入秒  (参数1:地址,参数2:数据,参数3:启用BCD处理)
        x_1302(addr_xbh,80,0);                //打开写保护
}
void main()
{
   x_1302(addr_ram,7,0);        //这里弄了我一个星期 。。现在什么情况还不明了。
        //上面一条代码是关键。如果没有这条代码我这里就写不进数据。起始这条
        //代码可以改成写其他的比如写RAM或在写年等等。
        //上面的一条代码可以说是初始化的 。。
        x_sj();
        while(1)
        {

                d_sj();        //读出时间然后写入数码管显示缓存
                sm();        //扫描数码管(也就是8位数码管显示)
        }
}

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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