基于STM32的DS1302时钟芯片驱动

基于STM32的DS1302时钟芯片驱动

/*************************************************************************************************************************
* 函数 : DS1302.H
* 功能 :  DS1302头文件
* 参数 :  无
* 返回 :  无
* 依赖 :  底层读写函数
* 作者 :  [email protected]
* 时间 :  2016-12-9
* 最后修改时间 : 
* 说明 : DS1302采用GPIO模拟SPI的方式
DS1302 LSB格式,上升沿写 下降沿读  BCD码存储
* 参考 :
*************************************************************************************************************************/ 
#include "sys.h"
#include "DS1302.h"
#include "delay.h"
//#include "type.h"
#include "stdio.h"


u8 u8time[8];
u8 rtc_init[8] = {
58, //秒  0
                  11, //分 1
                  14, //小时2
                  12,//日 3
                  1,//月 4
                  4,//周  
                  16,//2016年 6
                  0,//写效许 7

};


/*************************************************************************************************************************
* 函数 : void DS1302_GPIO_Init(void)
* 功能 :  配置STM32的GPIO和SPI接口,用于连接 DS1302
* 参数 :  无
* 返回 :  无
* 依赖 :  GPIO库函数
* 作者 :  [email protected]
* 时间 :  2016-12-9
* 最后修改时间 : 2017-1-4修改驱动
* 说明 : DS1302_DIO配置为开漏模式,此模式下能够实现真正的双向IO口
*************************************************************************************************************************/
void DS1302_GPIO_Init(void)
{
GPIO_InitTypeDef  GPIO_InitStructure;

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOD, ENABLE);
//使能PA,PD端口时钟
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
//
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;  //IO口速度为50MHz
 GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOA.8
}


 void Dio_In(void)
 {
GPIO_InitTypeDef  GPIO_InitStructure;
  
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOD, ENABLE);
//使能PA,PD端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 ;
 
GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_IPU; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//IO口速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure);

}
 
void  DIO_Out(void)
{
GPIO_InitTypeDef  GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOD, ENABLE);
//使能PA,PD端口时钟

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 ;
//LED0-->PA.8 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//IO口速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure);
//根据设定参数初始化GPIOA.8
}
/*************************************************************************************************************************
*函数         :  void DS1302_WriteByte(u8 data)
*功能         :  写一个Byte到DS1302
*参数         :  data:要写入的Byte
*返回         :  无
*依赖 : 底层宏定义
* 作者 :  [email protected]
* 时间 :  2016-12-09
* 最后修改时间: 
*说明         :  写一个字节的数据SCK上升沿写数据
*************************************************************************************************************************/
void DS1302_WriteByte(u8 addr,u8 data)
{
char  i=0;
  int Coda=0;
   Coda=(data<<8)|addr;
   En_Ss( );
  for(i=0;i<16;i++)
  {  
if((Coda&0x01)!=0)
         Set_Dio( );
       else
         Clr_Dio();
        Set_Sclk( );
        Coda=Coda>>1; 
        Clr_Sclk( );
  }
   Di_Ss( );
} 




/*************************************************************************************************************************
*函数         :  u8 DS1302_ReadByte(u8 addr)
*功能         :  从DS1302SPI总线上读取一个字节
*参数         :  addr:寄存器地址
*返回         :  读取到的数据
*依赖 : 底层宏定义
* 作者 :  [email protected]
* 时间 :  2016-12-09
* 最后修改时间: 
*说明         :  读一个字节的数据 SCK下降沿读数据
*************************************************************************************************************************/
u8 DS1302_ReadByte(u8 addr)
{
char i,Coda;
  Coda=addr;
  En_Ss( );
  for(i=0;i<8;i++)
  { 
if((Coda&0x01)!=0)
        Set_Dio( );
      else
        Clr_Dio( );
      Set_Sclk( );
          Coda=Coda>>1;
        Clr_Sclk( );
   }
  /************************************/
   Dio_In();   //读数据
     Coda=0;
   for(i=0;i<8;i++)
  {   
if( Read_Dio()!=0)
        Coda|=(1<<i);
        Set_Sclk( );
        Clr_Sclk( );
    }


   Di_Ss();
   DIO_Out();              
   return Coda ;
}




/*************************************************************************************************************************
*函数         :  void DS1302_WriteData(u8 addr,u8 data)
*功能         :  向指定寄存器写入一个字节的数据
*参数         :  addr:寄存器地址;data:需要写入的数据
*返回         :  无
*依赖 : 底层宏定义
* 作者 :  [email protected]
* 时间 :  2016-12-09
* 最后修改时间: 
*说明         :  
*************************************************************************************************************************/
void DS1302_WriteData(u8 addr,u8 data)
{
Di_Ss();
Clr_Sclk();
delay_us(1);
En_Ss();
delay_us(2);
DS1302_WriteByte(addr,data);
Di_Ss();
Clr_Sclk();
delay_us(1);
}




/*************************************************************************************************************************
*函数         :  void DS1302_ReadTime(u8 addr,u8 time[8])
*功能         :  处理数据并通过串口打印
*参数         :  read:要写入的Byte
*返回         :  无
*依赖 : 底层宏定义
* 作者 :  [email protected]
* 时间 :  2016-12-10
* 最后修改时间: 
*说明         :  
*************************************************************************************************************************/
void DS1302_ReadTime(u8 addr,u8 time[8])
{
char i,j,Coda;
u8 temp;
    Coda=addr;
En_Ss();
    for(i=0;i<8;i++)
{ 
if((Coda&0x01)!=0)
       Set_Dio();
      else
Clr_Dio();

      Set_Sclk();
      Coda=Coda>>1;
      Clr_Sclk();
    }
Dio_In();   //读数据
    for(i=0;i<8;i++ )
     { 
time[i]=0;
       for(j=0;j<8;j++ )
       { 
if( Read_Dio()!=0)
          time[i]|=(1<<j);
           Set_Sclk();
           Clr_Sclk();
        }
temp = time[i] / 16;
time[i] = temp * 10 + time[i] % 16;
      }
    Di_Ss();
    DIO_Out();     
} 




/*************************************************************************************************************************
*函数         :  void DS1302_Settime(u8 *Buffer)
*功能         :  对时
*参数         :  要写入年 月 日 时 分 秒
*返回         :  无
*依赖 : 底层宏定义
* 作者 :  [email protected]
* 时间 :  2016-12-10
* 最后修改时间: 
*说明         :  
*************************************************************************************************************************/
void DS1302_Settime(uint8_t addr,uint8_t time[8])
{
char i,j,ge;
int Coda=0;


  Coda=addr;
En_Ss();
for(i=0;i<8;i++)
//时间地址
  { 
if((Coda&0x01)!=0)
     Set_Dio();
    else
Clr_Dio();
      Set_Sclk();
      Coda=Coda>>1;
      Clr_Sclk();
}
    
for(i=0;i<8;i++) //时间数据
 { 
ge=time[i]%10;//个位数部分
time[i]=(time[i]/10)*16+ge;

Coda=time[i];
   for(j=0;j<8;j++)
   {  
if((Coda&0x01)!=0)
       Set_Dio();
       else
Clr_Dio(); 
 
         Set_Sclk();
         Coda=Coda>>1;
         Clr_Sclk();    
    }
}
  Di_Ss();
}





/*************************************************************************************************************************
* 函数 : DS1302.H
* 功能 :  DS1302头文件
* 参数 :  无
* 返回 :  无
* 依赖 :  底层读写函数
* 作者 :  [email protected]
* 时间 :  2016-12-9
* 最后修改时间 : 
* 说明 : DS1302采用GPIO模拟SPI的方式
DS1302 LSB格式,上升沿写 下降沿读
*************************************************************************************************************************/ 
#ifndef __DS1302_H
#define __DS1302_H


#include "sys.h"
//#include "type.h"
/*****************DS1302控制命令***************************************
*BIT7 BIT6  BIT5 BIT4  BIT3 BIT2  BIT1 BIT0
* 0数据不能写入 存取日历时钟Data
Addr4 Addr3 Addr2
Addr1 Addr0
写操作
* 1必须为1  存取RAM时钟Data 读操作
**********************************************************************/


//寄存器地址
typedef enum
{
DS1302_RdSec  = 0x81,  //BIT7: 0正常工作; 1:低功耗模式
DS1302_RdMin  = 0x83,
DS1302_RdHour 
= 0x85,
//BIT5: 0运行为12时; 1:24时
DS1302_RdDate  = 0x87,
DS1302_RdMonth
= 0x89,
DS1302_RdWeek  = 0x8b,
DS1302_RdYear  = 0x8d,
DS1302_RdProtect
= 0x8f,
//读保护
DS1302_RdTrickleCharge
= 0x91,
DS1302_RdClockBurst
= 0xbf,
DS1302_WrSec  = 0x80,  //BIT7: 0正常工作; 1:低功耗模式
DS1302_WrMin  = 0x82,
DS1302_WrHour  = 0x84,  //BIT5: 0运行为12时; 1:24时
DS1302_WrDate  = 0x86,
DS1302_WrMonth
= 0x88,
DS1302_WrWeek  = 0x8a,
DS1302_WrYear  = 0x8c,
DS1302_WrProtect
= 0x8e,
//写保护
DS1302_WrTrickleCharge
= 0x90,
}DS1302_RegAddr;


typedef enum
{
DS1302_WrClockBurst
= 0xbe,
//写时钟突发模式
DS1302_RdRamBurst
= 0xbf,
//读时钟突发模式
DS1302_WrRAMBurst
= 0xfe,
//写RAM突发模式
DS1302_RdRAMBurst
= 0xff,
//读RAM突发模式
}DS1302_MODE;


//定义时间结构体
typedef struct
{
unsigned char sec;
unsigned char min;
unsigned char hour;
unsigned char day;
unsigned char month;
unsigned char year;
}TIME_TypeDef;


//*****************DS1302控制命令*******************
//相对应的IO口配置移植时修改
#define DS1302_PORT GPIOB
#define DS1302_SCK GPIO_Pin_6
//DS1302_SCK
#define DS1302_DIO GPIO_Pin_7
//DS1302_DIO
#define DS1302_CE GPIO_Pin_5
//DS1302_CE


//寄存器IO口操作状态
#define Clr_Sclk() (GPIO_ResetBits(DS1302_PORT, DS1302_SCK))
#define Set_Sclk() (GPIO_SetBits(DS1302_PORT, DS1302_SCK))


#define Clr_Dio() (GPIO_ResetBits(DS1302_PORT, DS1302_DIO))
#define Set_Dio() (GPIO_SetBits(DS1302_PORT, DS1302_DIO))


#define Di_Ss() (GPIO_ResetBits(DS1302_PORT, DS1302_CE))
#define En_Ss() (GPIO_SetBits(DS1302_PORT, DS1302_CE))


#define Read_Dio() (GPIO_ReadInputDataBit(DS1302_PORT, DS1302_DIO))


extern u8 rtc_init[8];
extern u8 u8time[8];
/**********************************************函数声明**************************************************/
void DS1302_GPIO_Init(void); //配置STM32的GPIO和SPI接口
void DS1302_Settime(uint8_t addr,uint8_t time[8]);  //设置时间
void DS1302_ReadTime(u8 addr,u8 time[8]); //读取DS1302时间
#endif

猜你喜欢

转载自blog.csdn.net/weibo1230123/article/details/80253459
今日推荐