#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); } }