原创 ds1302时钟程序

2009-8-18 22:11 2656 1 1 分类: MCU/ 嵌入式

  1. #define uchar     unsigned char
    #define uint      unsigned int
    sbit T_CLK = P2^5; /*实时时钟时钟线引脚 */
    sbit T_IO = P2^6; /*实时时钟数据线引脚 */
    sbit T_RST = P2^7; /*实时时钟复位线引脚 */
    sbit ACC0=ACC^0;
    sbit ACC7=ACC^7;

    void   RTInputByte(uchar);       /* 输入 1Byte */
    uchar RTOutputByte(void);       /* 输出?1Byte */
    void   W1302(uchar, uchar);
    uchar R1302(uchar);
    void   Set1302(uchar *);         /* 设置时间 */
    void   Bcd2asc(uchar,uchar *);
    void   Get1302(uchar curtime[]); /* 读取1302当前时间 */
    void Init1302(void);
    /********************************************************************
    函 数 名:RTInputByte()
    功    能:实时时钟写入一字节
    说    明:往DS1302写入1Byte数据 (内部函数)
    入口参数:d 写入的数据 返 回 值:无
    ***********************************************************************/
    void RTInputByte(uchar d)
    {
        uchar i;
        ACC = d;
        for(i=8; i>0; i--)
        {
            T_IO = ACC0;           /*相当于汇编中的 RRC */
            T_CLK = 1;
            T_CLK = 0;
            ACC = ACC >> 1;
        }
    }
    /********************************************************************
    函 数 名:RTOutputByte()
    功    能:实时时钟读取一字节
    说    明:从DS1302读取1Byte数据 (内部函数)
    入口参数:无
    返 回 值:ACC
    ***********************************************************************/
    uchar RTOutputByte(void)
    {
        uchar i;
        for(i=8; i>0; i--)
        {
            ACC = ACC >>1;         /*相当于汇编中的 RRC */
            ACC7 = T_IO;
            T_CLK = 1;
            T_CLK = 0;
        }
        return(ACC);
    }
    /********************************************************************
    函 数 名:W1302()
    功    能:往DS1302写入数据
    说    明:先写地址,后写命令/数据 (内部函数)
    调    用:RTInputByte() , RTOutputByte()
    入口参数:ucAddr: DS1302地址, ucData: 要写的数据
    返 回 值:无


    ***********************************************************************/
    void W1302(uchar ucAddr, uchar ucDa)
    {
        T_RST = 0;
        T_CLK = 0;
        T_RST = 1;
        RTInputByte(ucAddr);       /* 地址,命令 */
        RTInputByte(ucDa);       /* 写1Byte数据*/
        T_CLK = 1;
        T_RST = 0;
    }
    /********************************************************************
    函 数 名:R1302()
    功    能:读取DS1302某地址的数据
    说    明:先写地址,后读命令/数据 (内部函数)
    调    用:RTInputByte() , RTOutputByte()
    入口参数:ucAddr: DS1302地址
    返 回 值:ucData :读取的数据
    ***********************************************************************/
    uchar R1302(uchar ucAddr)
    {
        uchar ucData;
        T_RST = 0;
        T_CLK = 0;
        T_RST = 1;
        RTInputByte(ucAddr);             /* 地址,命令 */
        ucData = RTOutputByte();         /* 读1Byte数据 */
        T_CLK = 1;
        T_RST = 0;
        return(ucData);
    }
    /********************************************************************
    函 数 名:BurstW1302T()
    功    能:往DS1302写入时钟数据(多字节方式)
    说    明:先写地址,后写命令/数据
    调    用:RTInputByte()
    入口参数:pWClock: 时钟数据地址 格式为: 秒 分 时 日 月 星期 年 控制
                                8Byte (BCD码)1B 1B 1B 1B 1B 1B 1B 1B
    返 回 值:无
    ***********************************************************************/
      
    void BurstW1302T(uchar *pWClock)
    {
        uchar i;
        W1302(0x8e,0x00);         // 控制命令,WP=0,写操作?
        T_RST = 0;
        T_CLK = 0;
        T_RST = 1;
        RTInputByte(0xbe);        // 0xbe:时钟多字节写命令
        for (i = 8; i>0; i--)     //8Byte = 7Byte 时钟数据 + 1Byte 控制
        {
            RTInputByte(*pWClock); // 写1Byte数据
            pWClock++;
        }
        T_CLK = 1;
        T_RST = 0;
    }        
    /********************************************************************
    函 数 名:BurstR1302T()
    功    能:读取DS1302时钟数据
    说    明:先写地址/命令,后读数据(时钟多字节方式)
    调    用:RTInputByte() , RTOutputByte()
    入口参数:pRClock: 读取时钟数据地址 格式为: 秒 分 时 日 月 星期 年
                                   7Byte (BCD码)1B 1B 1B 1B 1B 1B 1B
    返 回 值:无
    ***********************************************************************/


    void BurstR1302T(uchar *pRClock)
    {
        uchar i;
        T_RST = 0;
        T_CLK = 0;
        T_RST = 1;
        RTInputByte(0xbf);             // 0xbf:时钟多字节读命令
        for (i=8; i>0; i--)
        {
           *pRClock = RTOutputByte();   // 读1Byte数据
           pRClock++;
        }
        T_CLK = 1;
        T_RST = 0;
    }
    /********************************************************************
    函 数 名:BurstW1302R()
    功    能:往DS1302寄存器数写入数据(多字节方式)
    说    明:先写地址,后写数据(寄存器多字节方式)
    调    用:RTInputByte()
    入口参数:pWReg: 寄存器数据地址
    返 回 值:无
    ***********************************************************************/


    void BurstW1302R(uchar *pWReg)
    {
        uchar i;
        W1302(0x8e,0x00);         // 控制命令,WP=0,写操作
        T_RST = 0;
        T_CLK = 0;
        T_RST = 1;
        RTInputByte(0xfe);         // 0xbe:时钟多字节写命令
        for (i=31; i>0; i--)       //31Byte 寄存器数据
        {
            RTInputByte(*pWReg);    //写1Byte数据
            pWReg++;
        }
        T_CLK = 1;
        T_RST = 0;
    }
    /********************************************************************
    函 数 名:BurstR1302R()
    功    能:读取DS1302寄存器数据
    说    明:先写地址,后读命令/数据(寄存器多字节方式)
    调    用:RTInputByte() , RTOutputByte()
    入口参数:pRReg: 寄存器数据地址
    返 回 值:无
    ***********************************************************************/

    void BurstR1302R(uchar *pRReg)
    {
        uchar i;
        T_RST = 0;
        T_CLK = 0;
        T_RST = 1;
        RTInputByte(0xff);            // 0xff:时钟多字节读命令
        for (i = 31; i>0; i--)        //31Byte 寄存器数据
        {
            *pRReg = RTOutputByte(); // 读1Byte数据
            pRReg++;
        }
        T_CLK = 1;
        T_RST = 0;
    }
                        
    /********************************************************************
    函 数 名:Set1302()
    功    能:设置初始时间
    说    明:先写地址,后读命令/数据(寄存器多字节方式)
    调    用:W1302()
    入口参数:pClock: 设置时钟数据地址 格式为: 秒 分 时 日 月 星期 年
                                   7Byte (BCD码)1B 1B 1B 1B 1B 1B 1B
    返 回 值:无
    ***********************************************************************/
    void Set1302(uchar *pClock)
    {
        uchar i;
        uchar ucAddr = 0x80;
        W1302(0x8e,0x00);           /* 控制命令,WP=0,写操作?*/
        for(i =7; i>0; i--)
        {
            W1302(ucAddr,*pClock); /* 秒 分 时 日 月 星期 年 */
            pClock++;
            ucAddr +=2;
        }
        W1302(0x8e,0x80);           /* 控制命令,WP=1,写保护?*/
    }
    /********************************************************************
    函 数 名:Get1302()
    功    能:读取DS1302当前时间
    说    明:
    调    用:R1302()
    入口参数:ucCurtime: 保存当前时间地址。当前时间格式为: 秒 分 时 日 月 星期 年
                                           7Byte (BCD码)   1B 1B 1B 1B 1B 1B 1B
    返 回 值:无
    ***********************************************************************/
    void Get1302(uchar ucCurtime[])
    {
        uchar i;
        uchar ucAddr = 0x81;
        for (i=0; i<7; i++)
        { ucCurtime = R1302(ucAddr);/*格式为: 秒 分 时 日 月 星期 年 */
            ucAddr += 2;
        }
    }/***********************************************************************
    * 名称: Init1302
    * 说明:
    * 功能: 初始化DS1302
    * 调用:
    * 输入:
    * 返回值: 无
    *****************************************************************************/
    void Init1302(void)
    {
    W1302(0x8e,0x00); //控制写入WP=0
    //W1302(0x90,0xa5);
    W1302(0x80,0x00); //秒
    W1302(0x82,0x33); //分
    W1302(0x84,0x15); //时
    W1302(0x86,0x17); //日
    W1302(0x88,0x04); //月
    W1302(0x8a,0x05); //星期
    W1302(0x8c,0x09); //年
    W1302(0x8e,0x80);
    }
    /**************************************************************************
    * 名称: donetime
    * 说明:
    * 功能: 时间处理
    * 调用:
    * 输入:
    * 返回值: 无
    *****************************************************************************/




  2. /*********定义DS1302访问使用的端口******************/   
  3. #define Wait1us _NOP();   
  4. #define T_CLK_1 PORTD |= (1 << PD2) //CLK 1   
  5. #define T_CLK_0 PORTD &= ~(1 << PD2) //CLK 0   
  6.    
  7. #define T_IO_1 PORTD |= (1 << PD3) //I/O OUT 1   
  8. #define T_IO_0 PORTD &= ~(1 << PD3) //I/O OUT 0   
  9.    
  10. #define R_IO (PIND & (1 << PIND3)) //读取IO值   
  11.    
  12. #define T_RST_1 PORTD |= (1 << PD4) //RST 1   
  13. #define T_RST_0 PORTD &= ~(1 << PD4) //RST 0   
  14.    
  15. #define IO_OUT DDRD |= (1 << PD3) //设置I/O为输出   
  16. #define IO_IN {DDRD &= ~(1 << PD3); PORTD &= ~(1 << PD3);} //设置I/O为输入,不需要上拉电阻   
  17.    
  18. void SetByte(unsigned char DSAdree);    
  19. unsigned char GetByte(void);    
  20. void WriteDataToDS1302(unsigned char DSAdree, unsigned char DSData);   
  21. unsigned char ReadDataDS1302(unsigned char DSAdree);   
  22.    
  23. /***************初始化************/   
  24.    
  25. void InitDS1302(void)   
  26. {   
  27. DDRD |= ((1 << PD2) | (1 << PD4)); //设置PD2,PD4为输出   
  28. T_CLK_0;   
  29. T_RST_0;   
  30. WriteDataToDS1302(0x8E, 0x0);  //写保护关闭   
  31. Sec = ReadDataDS1302(0x81);   
  32. WriteDataToDS1302(0x80, (Sec & 0x7F));  //设置运行位   
  33. WriteDataToDS1302(0x90, 0xAB);  //启用电池充电,双二极管,8K电阻。   
  34. WriteDataToDS1302(0x8E, 0x80);  //写保护开启   
  35. }   
  36.    
  37. /********************************************************************  

  38. 函 数 名:SetByte()
  39. 功     能:向DS1302写入1Byte数据
  40. 输入参数:DSAdree 写入的数据  
  41. 返 回 值:无   

  42. ***********************************************************************/   
  43. void SetByte(unsigned char DSAdree)    
  44. {    
  45.      unsigned char i;   
  46.      DS = DSAdree;   
  47. IO_OUT; //设置端口为输出   
  48.     for(i = 8; i > 0; i --)   
  49.      {   
  50.         if (DS & 0x1)   
  51.    {   
  52.     T_IO_1;   
  53.    }   
  54.   else   
  55.    {   
  56.     T_IO_0;   
  57.    }   
  58.    T_CLK_1;   
  59.    Wait1us;   
  60.          T_CLK_0;   
  61.          DS = DS >> 1;    
  62.      }   
  63. IO_IN; //修改端口为输入,注意此项关键,否则可能烧毁DS1302   
  64. }   
  65. /********************************************************************  

  66. 函 数 名:GetByte()
  67. 功     能:从DS1302读取一字节
  68. 输入参数:无   
  69. 返 回 值:一个字节

  70. ***********************************************************************/   
  71. unsigned char GetByte(void)    
  72. {    
  73.      unsigned char i;   
  74. IO_IN; //设置端口为输入   
  75. DS = 0;   
  76.     for(i = 8; i > 0; i --)   
  77.      {   
  78.          DS = (DS >> 1);   
  79.   if (R_IO)   
  80.    {   
  81.     DS |= 0x80;   
  82.    }   
  83.          T_CLK_1;   
  84.    Wait1us;   
  85.          T_CLK_0;   
  86.      }   
  87.     return (DS);    
  88. }   
  89. /********************************************************************  

  90. 函 数 名:WriteDataToDS1302()
  91. 功     能:向DS1302写入数据
  92. 调     用:InputByte() , GetByte()
  93. 入口参数:DSAdree: DS1302地址, DSData: 要写的数据
  94. 返 回 值:无

  95. ***********************************************************************/   
  96. void WriteDataToDS1302(unsigned char DSAdree, unsigned char DSData)   
  97. {   
  98.      T_RST_0;   
  99.      T_CLK_0;   
  100.      T_RST_1;   
  101.      SetByte(DSAdree); // 地址,命令   
  102.      SetByte(DSData); // 写1Byte数据   
  103.      T_CLK_1;   
  104.      T_RST_0;   
  105. }    
  106. /********************************************************************  

  107. 函 数 名:ReadDataDS1302()
  108. 功     能:读取DS1302某地址的数据
  109. 调     用:RTInputByte() , RTOutputByte()
  110. 入口参数:ucAddr: DS1302地址
  111. 返 回 值:ucData :读取的数据

  112. ***********************************************************************/   
  113. unsigned char ReadDataDS1302(unsigned char DSAdree)   
  114. {   
  115.      unsigned char DSData;   
  116.      T_RST_0;   
  117.      T_CLK_0;   
  118.      T_RST_1;   
  119.      SetByte(DSAdree);             // 地址,命令   
  120.      DSData = GetByte();         // 读1Byte数据   
  121.      T_CLK_1;   
  122.      T_RST_0;   
  123.     return(DSData);   
  124. }   
  125.    
PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
1
关闭 站长推荐上一条 /3 下一条