/*************************************************************************************************************************
* 函数
: 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