207 lines
5.7 KiB
Plaintext
207 lines
5.7 KiB
Plaintext
#include "bsp_DS1302.h"
|
|
|
|
#define bsp_DS1302_DELAY() do{ \
|
|
__NOP();__NOP();__NOP();__NOP();\
|
|
__NOP();__NOP();__NOP();__NOP();\
|
|
__NOP();__NOP();__NOP();__NOP();\
|
|
__NOP();__NOP();__NOP();__NOP();\
|
|
__NOP();__NOP();__NOP();__NOP();\
|
|
}while(0)
|
|
|
|
|
|
#define RST_CLR HAL_GPIO_WritePin(DS1302_RST_GPIO_Port, DS1302_RST_Pin, GPIO_PIN_RESET )
|
|
#define RST_SET HAL_GPIO_WritePin(DS1302_RST_GPIO_Port, DS1302_RST_Pin, GPIO_PIN_SET )
|
|
|
|
#define IO_CLR HAL_GPIO_WritePin(DS1302_DIO_GPIO_Port, DS1302_DIO_Pin, GPIO_PIN_RESET )
|
|
#define IO_SET HAL_GPIO_WritePin(DS1302_DIO_GPIO_Port, DS1302_DIO_Pin, GPIO_PIN_SET )
|
|
#define IO_READ HAL_GPIO_ReadPin (DS1302_DIO_GPIO_Port, DS1302_DIO_Pin )
|
|
|
|
#define SCK_CLR HAL_GPIO_WritePin(DS1302_CLK_GPIO_Port, DS1302_CLK_Pin, GPIO_PIN_RESET )
|
|
#define SCK_SET HAL_GPIO_WritePin(DS1302_CLK_GPIO_Port, DS1302_CLK_Pin, GPIO_PIN_SET )
|
|
|
|
static void bsp_DS1302Init(void);
|
|
static void bsp_DS1302_Task(void);
|
|
static void bsp_DS1302_Set(bsp_DS1302_Time_t *pTime);
|
|
|
|
|
|
bsp_DS1302_t DS1302 =
|
|
{
|
|
.Init = bsp_DS1302Init,
|
|
.Task = bsp_DS1302_Task,
|
|
.Set = bsp_DS1302_Set,
|
|
};
|
|
|
|
|
|
bsp_DS1302_t *pDS1302 = &DS1302;
|
|
|
|
static void bsp_DS1302DataInput(void)
|
|
{
|
|
GPIO_InitTypeDef GPIO_InitStruct; //定义GPIO结构体
|
|
|
|
GPIO_InitStruct.Pin = DS1302_DIO_Pin;
|
|
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
|
HAL_GPIO_Init(DS1302_DIO_GPIO_Port, &GPIO_InitStruct);
|
|
}
|
|
|
|
static void bsp_DS1302DataOutput(void)
|
|
{
|
|
GPIO_InitTypeDef GPIO_InitStruct; //定义GPIO结构体
|
|
|
|
GPIO_InitStruct.Pin = DS1302_DIO_Pin;
|
|
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
|
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
|
HAL_GPIO_Init(DS1302_DIO_GPIO_Port, &GPIO_InitStruct);
|
|
}
|
|
|
|
/*向bsp_DS1302写入一字节数据*/
|
|
static void bsp_DS1302_write_byte(u8 Addr, u8 Data)
|
|
{
|
|
u8 i;
|
|
RST_SET; /*启动bsp_DS1302总线*/
|
|
|
|
bsp_DS1302_DELAY();
|
|
/*写入目标地址:addr*/
|
|
Addr = Addr & 0xFE;/*最低位置零*/
|
|
for(i=0; i<8; i++){
|
|
if(Addr&0x01) IO_SET;
|
|
else IO_CLR;
|
|
bsp_DS1302_DELAY();
|
|
SCK_SET;
|
|
bsp_DS1302_DELAY();
|
|
SCK_CLR;
|
|
bsp_DS1302_DELAY();
|
|
Addr = Addr >> 1;
|
|
}
|
|
|
|
/*写入数据:d*/
|
|
for(i=0; i<8; i++){
|
|
if(Data&0x01) IO_SET;
|
|
else IO_CLR;
|
|
bsp_DS1302_DELAY();
|
|
SCK_SET;
|
|
bsp_DS1302_DELAY();
|
|
SCK_CLR;
|
|
bsp_DS1302_DELAY();
|
|
Data = Data >> 1;
|
|
}
|
|
RST_CLR; /*停止bsp_DS1302总线*/
|
|
bsp_DS1302_DELAY();
|
|
}
|
|
|
|
/*从bsp_DS1302读出一字节数据*/
|
|
static u8 bsp_DS1302_read_byte(u8 Addr)
|
|
{
|
|
u8 i;
|
|
u8 temp;
|
|
RST_SET; /*启动bsp_DS1302总线*/
|
|
bsp_DS1302_DELAY();
|
|
|
|
/*写入目标地址:addr*/
|
|
Addr = Addr | 0x01;/*最低位置高*/
|
|
for(i=0; i<8; i++)
|
|
{
|
|
if(Addr&0x01)
|
|
{
|
|
IO_SET;
|
|
}
|
|
else
|
|
{
|
|
IO_CLR;
|
|
}
|
|
bsp_DS1302_DELAY();
|
|
SCK_SET;
|
|
bsp_DS1302_DELAY();
|
|
SCK_CLR;
|
|
bsp_DS1302_DELAY();
|
|
Addr = Addr >> 1;
|
|
}
|
|
|
|
bsp_DS1302DataInput();
|
|
/*输出数据:temp*/
|
|
for(i=0; i<8; i++)
|
|
{
|
|
temp = temp>>1;
|
|
if(IO_READ) temp |= 0x80;
|
|
else temp&=0x7F;
|
|
bsp_DS1302_DELAY();
|
|
SCK_SET;
|
|
bsp_DS1302_DELAY();
|
|
SCK_CLR;
|
|
bsp_DS1302_DELAY();
|
|
}
|
|
RST_CLR; /*停止bsp_DS1302总线*/
|
|
bsp_DS1302_DELAY();
|
|
bsp_DS1302DataOutput();
|
|
return temp;
|
|
}
|
|
|
|
static u8 HexToBCD(u8 code)
|
|
{
|
|
u8 temp;
|
|
temp = ((code / 10)<<4)+(code % 10);
|
|
return temp;
|
|
}
|
|
|
|
static void bsp_DS1302_Set(bsp_DS1302_Time_t *pTime)
|
|
{
|
|
bsp_DS1302_write_byte(BSP_DS1302_CONTROL_ADDR,0x00); //关闭写保护
|
|
bsp_DS1302_write_byte(BSP_DS1302_SEC_ADDR,0x80); //暂停
|
|
|
|
bsp_DS1302_write_byte(BSP_DS1302_YEAR_ADDR, HexToBCD(pTime->Year));
|
|
bsp_DS1302_write_byte(BSP_DS1302_MONTH_ADDR, HexToBCD(pTime->Month));
|
|
bsp_DS1302_write_byte(BSP_DS1302_DATA_ADDR, HexToBCD(pTime->Day));
|
|
bsp_DS1302_write_byte(BSP_DS1302_HOUR_ADDR, HexToBCD(pTime->Hour));
|
|
bsp_DS1302_write_byte(BSP_DS1302_MIN_ADDR, HexToBCD(pTime->Minute));
|
|
bsp_DS1302_write_byte(BSP_DS1302_SEC_ADDR, HexToBCD(pTime->Second));
|
|
|
|
bsp_DS1302_write_byte(BSP_DS1302_CONTROL_ADDR,0x80); //打开写保护
|
|
}
|
|
|
|
static void bsp_DS1302_Task(void)
|
|
{
|
|
u8 RegData;
|
|
|
|
RegData = bsp_DS1302_read_byte(BSP_DS1302_YEAR_ADDR);
|
|
pDS1302->Time.Year = (RegData/16)*10 + RegData%16;
|
|
|
|
RegData = bsp_DS1302_read_byte(BSP_DS1302_MONTH_ADDR);
|
|
pDS1302->Time.Month = (RegData/16)*10 + RegData%16;
|
|
|
|
RegData = bsp_DS1302_read_byte(BSP_DS1302_DATA_ADDR);
|
|
pDS1302->Time.Day = (RegData/16)*10 + RegData%16;
|
|
|
|
RegData = bsp_DS1302_read_byte(BSP_DS1302_HOUR_ADDR);
|
|
pDS1302->Time.Hour = (RegData/16)*10 + RegData%16;
|
|
|
|
RegData = bsp_DS1302_read_byte(BSP_DS1302_MIN_ADDR);
|
|
pDS1302->Time.Minute = (RegData/16)*10 + RegData%16;
|
|
|
|
RegData = bsp_DS1302_read_byte(BSP_DS1302_SEC_ADDR);
|
|
pDS1302->Time.Second = (RegData/16)*10 + RegData%16;
|
|
|
|
}
|
|
|
|
static void bsp_DS1302Init(void)
|
|
{
|
|
RST_SET;
|
|
SCK_CLR;
|
|
bsp_DS1302_Task();
|
|
if((pDS1302->Time.Year>99)||(pDS1302->Time.Month>12)||(pDS1302->Time.Day>31)||
|
|
(pDS1302->Time.Hour>23)||(pDS1302->Time.Minute>59)||(pDS1302->Time.Second>59))
|
|
{
|
|
pDS1302->Time.Year = 25;
|
|
pDS1302->Time.Month = 1;
|
|
pDS1302->Time.Day = 1;
|
|
pDS1302->Time.Hour = 0;
|
|
pDS1302->Time.Minute = 0;
|
|
pDS1302->Time.Second = 0;
|
|
bsp_DS1302_Set(&pDS1302->Time);
|
|
}
|
|
}
|
|
|
|
|
|
|