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