248 lines
6.3 KiB
C
248 lines
6.3 KiB
C
#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();\
|
||
__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 u8 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_PP;
|
||
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 u8 bsp_DS1302_Set(bsp_DS1302_Time_t *pTime)
|
||
{
|
||
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))
|
||
{
|
||
return USR_FALSE;
|
||
|
||
}
|
||
else
|
||
{
|
||
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); //打开写保护
|
||
return USR_TRUE;
|
||
}
|
||
}
|
||
|
||
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);
|
||
}
|
||
}
|