基于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<         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<            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



你可能感兴趣的:(ARM的学习)