春华的点点滴滴    电子产品设计与开发 https://bbs.21ic.com/?609753 [收藏] [复制] [RSS]

日志

基于PIC16F877A的DS1302时钟芯片--附c程序(原创)

已有 1178 次阅读2010-11-26 03:49 |个人分类:PIC|系统分类:单片机| PIC, 16F877A, DS1302, c程序

 


使用DS1302时主要注意的地方:


 


1.      在上电时,RST 必须为逻辑0 直至Vcc>2.0V同时SCLK RST 驱动至逻辑1 状态时必须为逻辑0


2.      数据输入是在SCLK上升沿,数据输出是在SCLK下降沿


3.      传输方式:低位先传输。


4.      时钟运行:秒寄存器的最高位(BIT7)是作为时钟控制位,当为逻辑1时,时钟停止,为0时钟运行。所以如果要时钟运行的话就必须将秒寄存器的最高位清0


5.      12/24小时模式:小时寄存器的第7位(最高位)是选择12小时制还是24小时制。当为逻辑1时选择12小时,逻辑0选择24小时。当为12小时制时,小时寄存器的第5位用来表示上午AM和下午PM,逻辑1的时候表示PM,逻辑0的时候表示AM


6.      在企图对DS1302操作之前,必须将WP清零。


7.      读写模式:有两种模式,可以单字节读写,以及连续多字节读写(burst mode)。在连续多字节读写时,即burst mode,地址是必须从地址00位开始的。如果对时钟操作,即CLOCK操作,则必须连续写满8个字节,如下图的8个字节。若是对RAM操作,则可以不必须写满31个字节。


      


8.      DS1302包含了实时时钟日历和31个字节的RAM,这里需要注意的是实时时钟日历的8个寄存器和31个字节的RAM是独立的,没有任何关系,不要混淆。31RAM字节可以做其他用途,如闹钟等。因为DS1302有电池供电,所以RAM的内容不会丢失,相当于EEPROM了。用户可以用来实现特别的要求。


9.      时序必须严格按照其数据手册上来。


10.  程序如下。(已调试通过)


       #include <htc.h>


//晶振4M,若晶振不一样,注意延时是否满足时序要求。


      #define DS1302_Data                    RB2
#define DS1302_Data_Dir            TRISB2
#define DS1302_CLK                    RB1
#define DS1302_Rst                      RB3


 


     #define BURST_CLOCK            0xbe
    #define BURST_RAM                  0xfe



    #define ADD_WP                       0x8e


    #define DISNABLE_WP            0x00



    #define OP_CLOCK               1
   #define OP_RAM                      0 



                                                                 //启动计时,24小时制,
UINT8 bank1 Clock_InitData[8] = {0x00,0x00,0x23,0x24,0x11,0x03,0x10,0x00};
                                  //秒  分   时  日   月  星期   年   控制
UINT8 CurClockData[8];//当前时钟数据


      void Delay_us(unsigned char dus);//函数声明
//***********************************************************************
//*功能: 初始化DS1302                     
//*参数: 无                      
//*返回: 无                                            
//***********************************************************************
void Init_DS1302(void)
{
    //初始化IO口
    TRISB &= ~0x0a;//RB1,RB3作为输出
    DS1302_Rst = 0;
    DS1302_CLK = 0;
    //初始化时间:
    DS1302_BurstWtData(OP_CLOCK,Clock_InitData,8);
   
}
//***********************************************************************
//*功能: 向DS1302写入一个字节                         
//*参数: 所需要写入的内容                          
//*返回: 无                                            
//***********************************************************************
void DS1302_WtOneByte(UINT8 wtdata)
{
   UINT8 i;
   DS1302_Data_Dir = OUTPUT;
   for (i=0;i<8;i++)
   {
       if (wtdata&0x01)//低位先发:
       {
           DS1302_Data = 1;
       }
       else
       {
           DS1302_Data = 0;
       }
       wtdata >>= 1;
       DS1302_CLK = 0;//上升沿写
       Delay_us(5);
       DS1302_CLK = 1;
       Delay_us(5);
   }
   Delay_us(10);
}
//***********************************************************************
//*功能: 向DS1302读出一个字节                         
//*参数: 无                     
//*返回: 读到的字节内容                                       
//***********************************************************************
UINT8 DS1302_RdOneByte(void)
{
   UINT8 i,Recv = 0;
   DS1302_Data_Dir = INPUT;
   for (i=0;i<8;i++)
   {
       Recv >>= 1;
       DS1302_CLK = 0;//下降沿读
       Delay_us(2);
       if (DS1302_Data)
       {
          Recv |= 0x80;
       }
       DS1302_CLK = 1;
       Delay_us(4);
   }
   Delay_us(10);
   return Recv;
}
//***********************************************************************
//*功能: 向DS1302写入单字节数据                     
//*参数: 数据内容               
//*返回: 无                                 
//***********************************************************************
void DS1302_WtData(UINT8 Addr,UINT8 wtdata)
{
   DS1302_CLK = 0;//在RST置1前清0
   Delay_us(2);
   DS1302_Rst = 1;
   Delay_us(5);
   DS1302_WtOneByte(Addr);
   DS1302_WtOneByte(wtdata);
   Delay_us(2);
   DS1302_Rst = 0;
   Delay_us(10);
}
//***********************************************************************
//*功能: 向DS1302读出单字节数据                     
//*参数: 数据内容               
//*返回: 无                                 
//***********************************************************************
UINT8 DS1302_RdData(UINT8 Addr)
{
   UINT8 RdTemp;
   DS1302_CLK = 0;
   Delay_us(2);
   DS1302_Rst = 1;
   Delay_us(5);
   DS1302_WtOneByte(Addr);
   RdTemp = DS1302_RdOneByte();
   Delay_us(2);
   DS1302_Rst = 0;
   Delay_us(10);
   return RdTemp;
}
//***********************************************************************
//*功能: 向DS1302连续写入多字节数据,Burst Mode                    
//*参数: 数据内容               
//*返回: 无                                 
//***********************************************************************
void DS1302_BurstWtData(UINT8 BurstType,UINT8 *wtp,UINT8 wtcnt)
{
   UINT8 i,Command;
   if (BurstType == OP_CLOCK)
   {
      Command = BURST_CLOCK;
      #if wtcnt > 8
      #error CLOCK MAX bytes is 8.
      #endif
   }
   else
   {
      Command = BURST_RAM;
   }
   DS1302_WtData(ADD_WP,DISNABLE_WP);
   Delay_us(5);
   DS1302_CLK = 0;
   Delay_us(2);
   DS1302_Rst = 1;
   Delay_us(5);
   DS1302_WtOneByte(Command);//写BURST指令


        for (i=0;i<wtcnt;i++)//连续写字节
   {
      DS1302_WtOneByte(*wtp);
      wtp++;
   }
   DS1302_Rst = 0;
   Delay_us(2);
}


      //***********************************************************************
//*功能: 向DS1302连续读出多字节数据,Burst Mode                    
//*参数: 数据内容               
//*返回: 无                                 
//***********************************************************************
void DS1302_BurstRdData(UINT8 BurstType,UINT8 *rdp,UINT8 rdcnt)
{
   UINT8 i,Command;
   if (BurstType == OP_CLOCK)
   {
      Command = BURST_CLOCK;
      #if wtcnt > 8
      #error CLOCK MAX bytes is 8.
      #endif
   }
   else
   {
      Command = BURST_RAM;
   }
   Command += 1;//读
   DS1302_CLK = 0;
   Delay_us(2);
   DS1302_Rst = 1;
   Delay_us(5);
   DS1302_WtOneByte(Command);//写BURST指令


         for (i=0;i<rdcnt;i++)//连续读出多字节
   {
      *rdp = DS1302_RdOneByte();
      rdp++;
   }
   DS1302_Rst = 0;
   Delay_us(2);
}


      //***********************************************************************
//*功能:粗略延时


      //*参数: 延时的NOP数,最大255    
//*返回: 无                                 
//***********************************************************************


      void Delay_us(unsigned char dus)
{
    while(dus--);
}


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)