#include "CH57x_common.h" #include "rtc.h" #include "DBG.h" #include #include "net.h" //êμ?êRTCêy?Y(ê?áù????êy?Y±íê??aê?????) S_RTC RTC_Raw_Data; S_RTC MCU_RTC_Data = { .year = 0x24, .month = 1, .day = 1, .week = 0, .hour = 0, .minute = 0, .second = 0, }; S_RTC Net_RTC_Data; //2024-08-03 网络时间 TIME_INFO_T g_time_info; /******************************************************************************* * Function Name : RTC_DATA_Type_Cast_DEC * Description : RTCêμ?êêy?Y′?′¢μ?D?ê?ê?ò?ê?áù??????DD′?′¢μ?£?ê1ó?ê±Dèòa??ê?áù????×a???aê?????êy êμày ê?áù???? ê????? 0x16 -> 16 *******************************************************************************/ uint8_t RTC_DATA_Type_Cast_DEC(uint8_t data) { uint8_t rev = 0; rev = (data / 16) * 10 + (data % 16); return rev; } void RTC_Init(void) { //RTC_SDA - PB8 //RTC_SCL - PB9 RTC_SDA_OUTPUT; RTC_SCL_OUTPUT; RTC_SDA_H; RTC_SCL_H; memset(&RTC_Raw_Data,0,sizeof(RTC_Raw_Data)); memset(&g_time_info,0,sizeof(TIME_INFO_T)); } void RTC_Wait(void) { __nop();__nop(); } /********?a??SD2058μ?IIC×ü??********/ void RTC_Start(void) { RTC_SDA_OUTPUT; RTC_Wait(); RTC_SDA_H; RTC_SCL_H; RTC_Wait(); RTC_SDA_L; RTC_Wait(); RTC_SCL_L; RTC_Wait(); } /********1?±?SD2058μ?IIC×ü??*******/ void RTC_Stop(void) { RTC_SDA_OUTPUT; RTC_SDA_L; RTC_SCL_L; RTC_Wait(); RTC_SCL_H; RTC_Wait(); RTC_SDA_H; } /*********·¢?í ACK*********/ void RTC_Ack(void) { RTC_SDA_OUTPUT; RTC_SCL_L; RTC_SDA_L; RTC_Wait(); RTC_SCL_H; RTC_Wait(); RTC_SCL_L; } /*********·¢?íNO ACK*********/ void RTC_NoAck(void) { RTC_SDA_OUTPUT; RTC_SCL_L; RTC_SDA_H; RTC_Wait(); RTC_SCL_H; RTC_Wait(); RTC_SCL_L; } /*********?áè?ACKD?o?*********/ uint8_t RTC_WaitAck(void) { uint8_t cnt = 0; RTC_SCL_L; RTC_SDA_INPUT; RTC_SDA_H; RTC_Wait(); RTC_SCL_H; while(RTC_SDA == 1) { cnt++; if(cnt > 250) return FALSE; } RTC_SCL_L; return TRUE; } /************MCU?òSD2058·¢?íò???×??ú*************/ void RTC_SendByte(uint8_t demand) { uint8_t i = 8; RTC_SDA_OUTPUT; while(i--) { RTC_SCL_L; __nop();__nop(); if(demand & 0x80) RTC_SDA_H; else RTC_SDA_L; demand <<= 1; RTC_Wait(); RTC_SCL_H; RTC_Wait(); } RTC_SCL_L; } /*********MCU′óSD2058?áè?ò?×??ú*********/ uint8_t RTC_ReceiveByte(void) { uint8_t i = 8; uint8_t data = 0; RTC_SDA_INPUT; RTC_SDA_H; while(i--) { data <<= 1; RTC_SCL_L; RTC_Wait(); RTC_SCL_H; RTC_Wait(); if(RTC_SDA != 0) data |= 0x01; } RTC_SCL_L; return data; } /******RTCD′ò???×??ú******/ uint8_t RTC_WriteOneByte(uint8_t DeviceAddress,uint8_t add,uint8_t data) { RTC_Start(); RTC_SendByte(DeviceAddress); RTC_WaitAck(); RTC_SendByte(add); RTC_WaitAck(); RTC_SendByte(data); RTC_WaitAck(); RTC_Stop(); return TRUE; } /******RTC?áò???×??ú******/ uint8_t RTC_ReadOneByte(uint8_t DeviceAddress,uint8_t add) { uint8_t date = 0; RTC_Start(); RTC_SendByte(DeviceAddress); if(!RTC_WaitAck()){RTC_Stop(); return FALSE;} RTC_SendByte(add); RTC_WaitAck(); RTC_Start(); RTC_SendByte(DeviceAddress+1); RTC_WaitAck(); date = RTC_ReceiveByte(); RTC_NoAck(); RTC_Stop(); return date; } /******D′SD2058?êDí3ìDò******/ uint8_t RTC_WriteTimeOn(void) { if(!RTC_WriteOneByte(RTC_Address,0x10,0x80))return FALSE; RTC_WriteOneByte(RTC_Address,0x0f,0x84); return TRUE; } /******D′SD2058???13ìDò******/ uint8_t RTC_WriteTimeOff(void) { if(!RTC_WriteOneByte(RTC_Address,0x0f,0))return FALSE; RTC_WriteOneByte(RTC_Address,0x10,0); return TRUE; } /******éè??SD2058±¨?ˉ?D???Yê?3ìDò?Yê?******/ void RTC_WriteALARM(void) //éè??±¨?ˉê±??£o2015?ê2??14è? 8£o00 { //??óDéè???′à′μ?ê±??2?óDD§ RTC_WriteTimeOn(); RTC_WriteOneByte(RTC_Address,0x09,0x08); //8ê± RTC_WriteOneByte(RTC_Address,0x0b,0x14); //14è? RTC_WriteOneByte(RTC_Address,0x0c,0x02); //02?? RTC_WriteOneByte(RTC_Address,0x0d,0x15); //15?ê RTC_WriteOneByte(RTC_Address,0x0e,0x74); //éè??±¨?ˉ?êDí£¨ê1?ü?ê?¢???¢è??¢D?ê±±¨?ˉ£? RTC_WriteOneByte(RTC_Address,0x10,0x92); //éè??INT?D????í¨£¨INTS1£?INTS0£?£??°±¨?ˉ?D??×ü?êDí??£¨INTAE£? RTC_WriteTimeOff(); } /******1?±?SD2058±¨?ˉ?D??3ìDò******/ void RTC_ClrALARM(void) //1?±?±¨?ˉ?D?? { RTC_WriteTimeOn(); RTC_WriteOneByte(RTC_Address,0x10,0x90); RTC_WriteTimeOff(); } /******éè??SD2058μ1??ê±?D???Yê?******/ void RTC_SetDjs(void) //éè??μ1??ê±?D?? { RTC_WriteTimeOn(); RTC_WriteOneByte(RTC_Address,0x10,0x0f);//?è??μ1??ê±?D??×ü?êDí??£¨INTDE£? RTC_WriteOneByte(RTC_Address,0x10,0xf4);//éè???ü?úD??D??£¨IM=1£?INT?D????í¨£¨INTS1£?INTS0£?£?????μ1??ê±?D??×ü?êDí??£¨INTDE£? RTC_WriteOneByte(RTC_Address,0x11,0x30);//?????¨ê±?÷?μ?ê?′£¨TDS1?¢TDS0£??a1/60HZ RTC_WriteOneByte(RTC_Address,0x13,0x05);//μ1??ê±3??μ??′??÷£?éè??8??μ1??ê±??êy3??죨5min£? RTC_WriteTimeOff(); } /******1?±?SD2058μ1??ê±?D??3ìDò******/ void RTC_ClrDjs(void) { RTC_WriteTimeOn(); RTC_WriteOneByte(RTC_Address,0x10,0xf0); RTC_WriteTimeOff(); } /******éè??SD2058?μ?ê?D???Yê?******/ void RTC_SetFrq(void) { RTC_WriteTimeOn(); RTC_WriteOneByte(RTC_Address,0x10,0xa1); //??í¨?μ?ê?D??£¨INTS1£?INTS0£?£?éè???μ?ê?D??×ü?êDí??£¨INTFE£? RTC_WriteOneByte(RTC_Address,0x11,0x09); //éè??2Hz?μ?ê?D?? RTC_WriteTimeOff(); } /******1?±?SD2058?μ?ê?D??******/ void RTC_ClrFrq(void) { RTC_WriteTimeOn(); RTC_WriteOneByte(RTC_Address,0x10,0xa0); RTC_WriteTimeOff(); } //|************IICá?D??á?à??×??ú************| uint8_t RTCReadSerial(uint8_t DeviceAddress, uint8_t Address, uint8_t len,uint8_t *ps) { uint8_t i; RTC_Start(); RTC_SendByte(DeviceAddress); if(!RTC_WaitAck()){RTC_Stop(); return FALSE;} RTC_SendByte(Address); //éè??òa?áμ?μ??· RTC_WaitAck(); RTC_Start(); RTC_SendByte(DeviceAddress+1); RTC_WaitAck(); for(i=0;iyear = MCU_RTC_Data.year; psRTC->month = MCU_RTC_Data.month; psRTC->day = MCU_RTC_Data.day; psRTC->hour = MCU_RTC_Data.hour; psRTC->minute = MCU_RTC_Data.minute; psRTC->second = MCU_RTC_Data.second; psRTC->week = MCU_RTC_Data.week; /* CSIO时间读取 结束*/ }else{ /* 软件计时 开始 */ //服务器的当前时间+本地计数 uint32_t rtc_tick = 0; rtc_tick = RTC_Conversion_To_Unix(&Net_RTC_Data); //rtc_tick += rtc_hour*3600+rtc_min*60+rtc_sec; rtc_tick += SysTick_1s - g_time_info.Mcu_GetTime_tick; Unix_Conversion_To_RTC(psRTC,rtc_tick); /* 软件计时 结束 */ } return 0; } uint8_t RTC_WriteDate(S_RTC SetRTC) { MCU_RTC_Data.year = SetRTC.year; MCU_RTC_Data.month = SetRTC.month; MCU_RTC_Data.day = SetRTC.day; MCU_RTC_Data.hour = SetRTC.hour; MCU_RTC_Data.minute = SetRTC.minute; MCU_RTC_Data.second = SetRTC.second; MCU_RTC_Data.week = SetRTC.week; // g_time_info.Mcu_GetTime_tick = SysTick_1s; //记录当前设置时间 return 0; } uint8_t NetRTC_WriteDate(S_RTC SetRTC) { Net_RTC_Data.year = SetRTC.year; Net_RTC_Data.month = SetRTC.month; Net_RTC_Data.day = SetRTC.day; Net_RTC_Data.hour = SetRTC.hour; Net_RTC_Data.minute = SetRTC.minute; Net_RTC_Data.second = SetRTC.second; Net_RTC_Data.week = SetRTC.week; g_time_info.Mcu_GetTime_tick = SysTick_1s; //记录当前设置时间 return 0; } #elif (USE_CORE_TYPE == 2) //ê1ó?C1o?D?°? /******?áSD2058êμê±êy?Y??′??÷******/ uint8_t RTC_ReadDate(S_RTC *psRTC) { RTC_Start(); RTC_SendByte(RTC_Address+1); if(!RTC_WaitAck()){RTC_Stop(); return FALSE;} psRTC->second=RTC_ReceiveByte(); RTC_Ack(); psRTC->minute=RTC_ReceiveByte(); RTC_Ack(); psRTC->hour=RTC_ReceiveByte()&0x7F; RTC_Ack(); psRTC->week=RTC_ReceiveByte(); RTC_Ack(); psRTC->day=RTC_ReceiveByte(); RTC_Ack(); psRTC->month=RTC_ReceiveByte(); RTC_Ack(); psRTC->year=RTC_ReceiveByte(); RTC_NoAck(); RTC_Stop(); return TRUE; } /******D′SD2058êμê±êy?Y??′??÷******/ //D′ê±??2ù×÷òa?óò?′???êμê±ê±????′??÷(00H~06H)òà′?D′è?£? //2??éò?μ¥?à??7??ê±??êy?Y?Dμ??3ò?????DDD′2ù×÷,·??ò?é?ü?áòy?eê±??êy?Yμ?′í?ó????. //òaDT?????D?3ò???êy?Y , ó|ò?′?D?D′è?è?2? 7 ??êμê±ê±?óêy?Y. uint8_t RTC_WriteDate(S_RTC SetRTC) { S_RTC *psRTC; psRTC=&SetRTC; RTC_WriteTimeOn(); //ê1?ü£??a?? RTC_Start(); RTC_SendByte(RTC_Address); if(!RTC_WaitAck()){RTC_Stop(); return FALSE;} RTC_SendByte(0x00); //éè??D′?eê?μ??· RTC_WaitAck(); RTC_SendByte(psRTC->second); //second RTC_WaitAck(); RTC_SendByte(psRTC->minute); //minute RTC_WaitAck(); RTC_SendByte(psRTC->hour|0x80); //hour ,í?ê±éè??D?ê±??′??÷×?????£¨0£o?a12D?ê±??£?1£o?a24D?ê±??£? RTC_WaitAck(); RTC_SendByte(psRTC->week); //week RTC_WaitAck(); RTC_SendByte(psRTC->day); //day RTC_WaitAck(); RTC_SendByte(psRTC->month); //month RTC_WaitAck(); RTC_SendByte(psRTC->year); //year RTC_WaitAck(); RTC_Stop(); RTC_WriteTimeOff(); //ê1?ü£?1??? return TRUE; } #endif /*1S?áè?ò?′?*/ void RTC_TASK(void) { static uint32_t RTC_Tick = 0; static uint8_t r_minute = 0; //2025-12-09 修改当处于CSIO读取时间时,Log_Time_ms无法更新时间戳,导致日志时间不正确 if(SysTick_1ms - RTC_Tick >= 1000) { RTC_Tick = SysTick_1ms; RTC_ReadDate(&RTC_Raw_Data); if(r_minute != RTC_Raw_Data.minute) { r_minute = RTC_Raw_Data.minute; Log_Time_ms = SysTick_1ms; } if(server_info.sync_tick==0x01) { server_info.sync_tick = 0x02; } } } /******************************************************************************* * Function Name : RTC_TimeDate_Correct_Figure * Description : RTC时间数据是否为有效数据内容 不允许出现 A~F * Return : 0x00:数据内容正常;0x01:数据内容不正确 *******************************************************************************/ uint8_t RTC_TimeDate_Correct_Figure(uint8_t data){ uint8_t temp_num = data; if( ((temp_num & 0x0F) < 0x0A) ){ temp_num >>= 4; if( ((temp_num & 0x0F) < 0x0A) ){ return 0x00; } } return 0x01; } /******************************************************************************* * Function Name : HEX_data_conversion_to_DEC * Description : ??ê?áù????±í′?μ?ê?????êy?Y×a???aêμ?êμ?ê?????êy?Y 0x20 -> 20 * Return : None *******************************************************************************/ uint8_t HEX_Conversion_To_DEC(uint8_t c_num) { uint8_t rev_num = 0; rev_num = (c_num/16)*10 + (c_num%16); return rev_num; } /******************************************************************************* * Function Name : HEX_data_conversion_to_DEC * Description : ??ê?????êy?Y×a???aê?áù????·?ê?±í′?êy?Y 20 -> 0x20 * Return : None *******************************************************************************/ uint8_t DEV_Conversion_To_HEX(uint8_t c_num) { uint8_t rev_num = 0; rev_num = (c_num/10)*16 + (c_num%10); return rev_num; } /******************************************************************************* * Function Name : RTC_Conversion_To_UTC * Description : ??RTCê±??×a?ˉ?aUTCê±?? * Return : None *******************************************************************************/ uint32_t RTC_Conversion_To_Unix(S_RTC *rtc_time) { uint32_t timestamp = 0; struct tm test_time; // Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"RTCê±??: 20%X-%X-%X %X:%X:%X D??ú%X\r\n",rtc_time->year,rtc_time->month,rtc_time->day,rtc_time->hour,rtc_time->minute,rtc_time->second,rtc_time->week); test_time.tm_year = HEX_Conversion_To_DEC(rtc_time->year) + 2000 - 1900; if(rtc_time->month != 0x00) { test_time.tm_mon = HEX_Conversion_To_DEC(rtc_time->month) - 1; }else { test_time.tm_mon = 1; } test_time.tm_mday = HEX_Conversion_To_DEC(rtc_time->day); test_time.tm_hour = HEX_Conversion_To_DEC(rtc_time->hour); test_time.tm_min = HEX_Conversion_To_DEC(rtc_time->minute); test_time.tm_sec = HEX_Conversion_To_DEC(rtc_time->second); test_time.tm_isdst = -1; timestamp = mktime(&test_time); //?a×a?ˉμ?±ê??μ?UTCê±??′á /*±±??ê±???1Dèòa??è¥8D?ê±*/ timestamp -= 8*3600; return timestamp; } /******************************************************************************* * Function Name : UTC_Conversion_To_RTC * Description : ??UTCê±??×a?ˉ?aRTCê±?? * Return : None *******************************************************************************/ void Unix_Conversion_To_RTC(S_RTC *rtc_time,uint32_t utc_tick) { uint8_t temp = 0; time_t temp_tick = utc_tick + 8*3600; /*±±??ê±??????3é±ê×??1Dèòa?óé?8D?ê±*/ struct tm *test_time; test_time = localtime(&temp_tick); temp = ( 1900 + test_time->tm_year ) - 2000; rtc_time->year = DEV_Conversion_To_HEX(temp); temp = 1 + test_time->tm_mon; rtc_time->month = DEV_Conversion_To_HEX(temp); temp = test_time->tm_mday; rtc_time->day = DEV_Conversion_To_HEX(temp); temp = test_time->tm_hour; rtc_time->hour = DEV_Conversion_To_HEX(temp); temp = test_time->tm_min; rtc_time->minute = DEV_Conversion_To_HEX(temp); temp = test_time->tm_sec; rtc_time->second = DEV_Conversion_To_HEX(temp); temp = test_time->tm_wday; rtc_time->week = DEV_Conversion_To_HEX(temp); // strftime( tmpbuf, 128, "Today is %A, day %d of %B in the year %Y.\n", test_time); // Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"%s",tmpbuf); // Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"RTCê±??: 20%X-%X-%X %X:%X:%X D??ú%X\r\n",rtc_time->year,rtc_time->month,rtc_time->day,rtc_time->hour,rtc_time->minute,rtc_time->second,rtc_time->week); }