Files
caocong 95916b9995 fix:修改UDP通讯中,取电变化上报机制
1、问题点:当RCU网络状态异常的情况下,网络还处于协商状态下,还未进入正常通讯环节时,取电变化不会进行判断。这会导致取电变化上报与实际产生取电状态时间点对不上。
2、将BLV_C1F_Module代码上传至Gitea,之前代码修改记录请查看 .\BasicCode\Readme.txt
2026-01-23 09:23:12 +08:00

578 lines
15 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "CH57x_common.h"
#include "rtc.h"
#include "DBG.h"
#include <time.h>
#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;
}
/******DSD2058?ê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;
}
/******DSD2058???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;i<len-1;i++,ps++)
{
*ps=RTC_ReceiveByte(); //?áêy?Y
RTC_Ack();
}
*ps=RTC_ReceiveByte();
RTC_NoAck();
RTC_Stop();
return TRUE;
}
//|******************IICá?D?D?à??×??ú******************|
uint8_t RTCWriteSerial(uint8_t DeviceAddress, uint8_t Address, uint8_t len,uint8_t *ps)
{
uint8_t i;
if(!RTC_WriteTimeOn()) return FALSE;
RTC_Start();
RTC_SendByte(DeviceAddress); //?÷?tμ??·
RTC_WaitAck();
RTC_SendByte(Address); //éè???eê?μ??·
RTC_WaitAck();
for(i=0;i<len;i++)
{
RTC_SendByte(*(ps++));
RTC_Ack();
}
RTC_Stop();
RTC_WriteTimeOff();
return TRUE;
}
#if (USE_CORE_TYPE == 1) //ê1ó?C1Fo?D?°?
uint8_t RTC_ReadDate(S_RTC *psRTC)
{
if(g_time_info.time_select == 0x02){
/* CSIO时间读取 开始*/
psRTC->year = 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;
}
/******DSD2058êμê±êy?Y????÷******/
//Dê±??2ù×÷òa?óò????êμê±ê±??????÷(00H~06H)òà′?Dè?£?
//2??éò?μ¥?à??7??ê±??êy?Y?Dμ??3ò?????DDD×÷,·??ò?é?ü?áò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);
}