DS1302时钟芯片的学习

 

串行传输时序:
 
并行传输时序:
/********************************************************************
* 文件名  : 时钟DS1302LCD.c
* 描述    :  该文件实现用DS1302来实现日历和时钟功能,液晶1602上显示出来。
* 创建人  : 东流,2009年4月10日
* 版本号  : 2.0
***********************************************************************/
#include<reg52.h>
#include<intrins.h>

#define uchar unsigned char
#define uint  unsigned int

sbit ACC0 = ACC^0;//累加器第一位
sbit ACC7 = ACC^7;//累加器第七位

sbit T_CLK = P1^6; /*实时时钟时钟线引脚 */
sbit T_IO = P3^5; /*实时时钟数据线引脚 */
sbit T_RST = P1^7; /*实时时钟复位线引脚 */
/********************************************************************
* 名称 :  v_RTInputByte()
* 功能 :  往DS1302写入1Byte数据
* 输入 :  ucDa 写入的数据
* 输出 :  无
***********************************************************************/
void v_RTInputByte(uchar ucDa)
{
        uchar i;
        ACC = ucDa;     //ACC为8位,即1Byte
        T_RST = 1;      //ret置高,开始传送数据
        for(i=8; i>0; i--)
        {
                T_IO = ACC0;    //要写入的第一位送给IO
                T_CLK = 1;      //产生一个始终震荡
                T_CLK = 0;
                ACC = ACC >> 1;         //右移位,使之继续传送
        }
}

/********************************************************************
* 名称  :   uc_RTOutputByte()
* 功能  :   从DS1302读取1Byte数据
* 输入  : 无
* 返回值:   ACC
***********************************************************************/
uchar uc_RTOutputByte(void)
{
        uchar i;
        T_RST = 1;      //ret置高,开始接收数据
        for(i=8; i>0; i--)
        {
                ACC = ACC >>1;
                //T_IO=1;       我觉得这里不对
                ACC7 = T_IO;
                T_CLK = 1;
                T_CLK = 0;
        }
        return(ACC);
}

/********************************************************************
* 名称   :   v_W1302(uchar ucAddr, uchar ucDa)
* 功能   :   往DS1302写入数据
* 输入   :   ucAddr: DS1302地址, ucDa: 要写的数据
* 返回值 :   无
***********************************************************************/
void v_W1302(uchar ucAddr, uchar ucDa)
{
        T_RST = 0;
        T_CLK = 0;
        T_RST = 1;
        v_RTInputByte(ucAddr);   // 写地址
        _nop_();
        _nop_();
        v_RTInputByte(ucDa);     // 写1Byte数据
        T_CLK = 1;
        T_RST = 0;
}

/********************************************************************
* 名称   :  uc_R1302(uchar ucAddr)
* 功能   :  读取DS1302某地址的数据
* 输入   :  ucAddr: DS1302地址
* 返回值 :  ucDa :读取的数据
***********************************************************************/
uchar uc_R1302(uchar ucAddr)
{
        uchar ucDa;
        T_RST = 0;
        T_CLK = 0;
        T_RST = 1;
        v_RTInputByte(ucAddr);    //写地址,命令
        _nop_();
        _nop_();
        ucDa = uc_RTOutputByte(); //读1Byte数据
        T_CLK = 1;
        T_RST = 0;
        return(ucDa);
}

/********************************************************************
* 名称   :  v_BurstW1302T
* 功能   :  往DS1302写入时钟数据(多字节方式)
* 输入   :  pSecDa: 时钟数据地址 格式为: 秒 分 时 日 月 星期 年 控制
*                                                  8Byte (BCD码) 1B 1B 1B 1B 1B 1B  1B  1B
* 返回值 :  无
***********************************************************************/
void v_BurstW1302T(uchar *pSecDa)       //*pSecDa指针,有可能是字符串
{
        uchar i;
        v_W1302(0x8e, 0x00);          //控制命令,WP=0,写操作
        T_RST = 0;
        T_CLK = 0;
        T_RST = 1;
        v_RTInputByte(0xbe);          //0xbe:时钟多字节写命令
//在DS1302内部寄存器中,关于时钟的
//时钟多字节:1011 111RD/w 即最后一位高时为读,低时为写
//WP为00时,为写操作,WP为80时,为写保护。。通过,控制的地址来进行更改WP的值。

        for(i=8; i>0; i--)            //8Byte = 7Byte 时钟数据 + 1Byte 控制
        {
                v_RTInputByte(*pSecDa);   //写1Byte数据
                pSecDa++;
        }
        T_CLK = 1;
        T_RST = 0;
}

/********************************************************************
* 名称   :  v_BurstR1302T(uchar *pSecDa)
* 功能   :  读取DS1302时钟数据
* 输入   :  pSecDa: 时钟数据地址 格式为: 秒 分 时 日 月 星期 年
*                                              7Byte (BCD码) 1B 1B 1B 1B 1B 1B   1B
* 返回值 :  ucDa :读取的数据
***********************************************************************/
void v_BurstR1302T(uchar *pSecDa)
{
        uchar i;
        T_RST = 0;
        T_CLK = 0;
        T_RST = 1;
        v_RTInputByte(0xbf);               //0xbf:时钟多字节读命令
        for(i=8; i>0; i--)
        {
                *pSecDa = uc_RTOutputByte();   //读1Byte数据
                pSecDa++;
        }
        T_CLK = 1;
        T_RST = 0;
}

/********************************************************************
* 名称   :  v_BurstW1302R(uchar *pReDa)
* 功能   :  往DS1302寄存器数写入数据(多字节方式)
* 输入   :  pReDa: 寄存器数据地址
* 返回值 :  无
***********************************************************************/
void v_BurstW1302R(uchar *pReDa)
{
        uchar i;
        v_W1302(0x8e,0x00);         //控制命令,WP=0,写操作
        T_RST = 0;
        T_CLK = 0;
        T_RST = 1;
        v_RTInputByte(0xfe);       //0xbe:时钟多字节写命令
        for(i=31; i>0; i--)        //31Byte 寄存器数据
        {
                v_RTInputByte(*pReDa); //写1Byte数据
                pReDa++;
        }
        T_CLK = 1;
        T_RST = 0;
}

/********************************************************************
* 名称   :  v_BurstR1302R(uchar *pReDa)
* 功能   :  读取DS1302寄存器数据
* 输入   :  pReDa: 寄存器数据地址
* 返回值 :  无
***********************************************************************/
void v_BurstR1302R(uchar *pReDa)
{
        uchar i;
        T_RST = 0;
        T_CLK = 0;
        T_RST = 1;
        v_RTInputByte(0xff);            //0xbf:时钟多字节读命令
        for(i=31; i>0; i--)             //31Byte 寄存器数据
        {
                *pReDa = uc_RTOutputByte(); //读1Byte数据
                pReDa++;
        }
        T_CLK = 1;
        T_RST = 0;
}

/********************************************************************
* 名称  :  v_Set1302(uchar *pSecDa)
* 功能  :  设置初始时间
* 输入  :  pSecDa: 初始时间地址。初始时间格式为: 秒 分 时 日 月 星期 年
*                                                                  7Byte (BCD码) 1B 1B 1B 1B 1B 1B  1B
* 返回值: 无
***********************************************************************/
void v_Set1302(uchar *pSecDa)
{
        uchar i;
        uchar ucAddr = 0x80;
        v_W1302(0x8e, 0x00);            //控制命令,WP=0,写操作
        for(i=7; i>0; i--)
        {
                v_W1302(ucAddr, *pSecDa);   // 秒 分 时 日 月 星期 年
                pSecDa++;
                ucAddr += 2;
                   //地址上相间隔为0x02
        }
        v_W1302(0x8e, 0x80);            //控制命令,WP=1,写保护
}

/********************************************************************
* 名称   : v_Get1302(uchar ucCurtime[])
* 功能   : 读取DS1302当前时间
* 输入   : ucCurtime: 保存当前时间地址。当前时间格式为: 秒 分 时 日 月 星期 年
*                                         7Byte (BCD码) 1B 1B 1B 1B 1B  1B  1B
* 返回值 : 无
***********************************************************************/
void v_Get1302(uchar ucCurtime[])
{
        uchar i;
        uchar ucAddr = 0x81;
        for(i=0; i<7; i++)
        {
                ucCurtime[i] = uc_R1302(ucAddr);    //格式为: 秒 分 时 日 月 星期 年
                ucAddr += 2;
        }
}

/********************************************************************
* 名称 : dectobcd(uchar dec)
* 功能 : DEC码转换为BCD码
* 输入 : dec码
* 输出 : bcd码
***********************************************************************/
uchar dectobcd(uchar dec)
{
        uchar bcd;
        bcd = 0;
        while(dec >= 10)
        {              
                dec -= 10;                         
                bcd++;
        }
        bcd <<= 4;      //将dec的十位放在bcd中,bcd将其左移4位
        bcd |= dec;     //将dec的个位放在bcd的第四位中
        return bcd;
}

/********************************************************************
* 名称 : bcdtodec(uchar bcd)
* 功能 : BCD码转换为DEC码
* 输入 : bcd码
* 输出 : dec码
***********************************************************************/
uchar bcdtodec(uchar bcd)
{
        uchar data1;
        data1 = bcd & 0x0f;     //取BCD低4位
        bcd = bcd & 0x70;       //剔除BCD的最高位和低4位。
        data1 += bcd >> 1;
        data1 += bcd >> 3;      //用位移代替乘
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值