2025-09-30 11:56:06 +08:00
|
|
|
|
/******************************************************************************
|
|
|
|
|
|
Filename: ESP32_Clock.c
|
|
|
|
|
|
Revised: $Date: 2019-12-02
|
|
|
|
|
|
Revision:
|
|
|
|
|
|
|
|
|
|
|
|
Description: ESP32 Clock definition and manipulation functions.
|
|
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
|
|
* INCLUDES
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include "ESP32_Clock.h"
|
|
|
|
|
|
#include "zigbee_fun.h"
|
|
|
|
|
|
#include "nvs_eepom.h"
|
|
|
|
|
|
#include "custom.h"
|
|
|
|
|
|
|
|
|
|
|
|
// #define LOG_TAG "RTC" // 该模块对应的标签。不定义时,默认:NO_TAG
|
|
|
|
|
|
#define LOG_LVL LOG_LVL_DBG // 该模块对应的日志输出级别。不定义时,默认:调试级别
|
|
|
|
|
|
#include <ulog.h> // 必须在 LOG_TAG与LOG_LVL下面
|
|
|
|
|
|
|
|
|
|
|
|
//TimerHandle_t rtc_time_handle = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
|
|
* MACROS
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#define YearLength(yr) (IsLeapYear(yr) ? 366 : 365)
|
|
|
|
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
|
|
* CONSTANTS
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
// (MAXCALCTICKS * 5) + (max remainder) must be <= (uint16_t max),
|
|
|
|
|
|
// so: (13105 * 5) + 7 <= 65535
|
|
|
|
|
|
#define MAXCALCTICKS ((uint16_t)(13105))
|
|
|
|
|
|
|
|
|
|
|
|
#define BEGYEAR 1900 // UTC started at 00:00:00 January 1, 1900
|
|
|
|
|
|
|
|
|
|
|
|
#define DAY 86400UL // 24 hours * 60 minutes * 60 seconds
|
|
|
|
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
|
|
* TYPEDEFS
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
|
|
* GLOBAL VARIABLES
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
|
|
* EXTERNAL VARIABLES
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
|
|
* EXTERNAL FUNCTIONS
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2025-09-30 13:01:24 +08:00
|
|
|
|
|
|
|
|
|
|
int isLeapYear(int year)
|
|
|
|
|
|
{
|
|
|
|
|
|
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int daysInMonth(int year, int month)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (month == 2)
|
|
|
|
|
|
{
|
|
|
|
|
|
return isLeapYear(year) ? 29 : 28;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (month == 4 || month == 6 || month == 9 || month == 11)
|
|
|
|
|
|
{
|
|
|
|
|
|
return 30;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
return 31;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
long dateToEpoch(int year, int month, int day, int hour, int minute, int second)
|
|
|
|
|
|
{
|
|
|
|
|
|
int days = 0;
|
|
|
|
|
|
|
|
|
|
|
|
for (int y = 1970; y < year; y++)
|
|
|
|
|
|
{
|
|
|
|
|
|
days += isLeapYear(y) ? 366 : 365;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (int m = 1; m < month; m++)
|
|
|
|
|
|
{
|
|
|
|
|
|
days += daysInMonth(year, m);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
days += day - 1;
|
|
|
|
|
|
|
|
|
|
|
|
long seconds = days * 86400 + hour * 3600 + minute * 60 + second;
|
|
|
|
|
|
|
|
|
|
|
|
return seconds;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2025-09-30 11:56:06 +08:00
|
|
|
|
/*********************************************************************
|
|
|
|
|
|
* LOCAL VARIABLES
|
|
|
|
|
|
*/
|
|
|
|
|
|
//static uint16_t previousLLTimerTick = 0;
|
|
|
|
|
|
//static uint16_t remUsTicks = 0;
|
|
|
|
|
|
//static uint16_t timeMSec = 0;
|
|
|
|
|
|
|
|
|
|
|
|
// number of seconds since 0 hrs, 0 minutes, 0 seconds, on the
|
|
|
|
|
|
// 1st of January 1900 UTC
|
|
|
|
|
|
//UTCTime esp32_timeSeconds = 0;
|
|
|
|
|
|
//struct tm timeinfo;
|
|
|
|
|
|
//char strftime_buf[64];
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
|
|
* LOCAL FUNCTION PROTOTYPES
|
|
|
|
|
|
*/
|
|
|
|
|
|
static uint8_t monthLength( uint8_t lpyr, uint8_t mon );
|
|
|
|
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
|
|
* FUNCTIONS
|
|
|
|
|
|
*********************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
|
|
* @fn esp32_setClock
|
|
|
|
|
|
*
|
|
|
|
|
|
* @brief Set the new time. This will only set the seconds portion
|
|
|
|
|
|
* of time and doesn't change the factional second counter.
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param newTime - number of seconds since 0 hrs, 0 minutes,
|
|
|
|
|
|
* 0 seconds, on the 1st of January 1900 UTC
|
|
|
|
|
|
*
|
|
|
|
|
|
* @return none
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
void esp32_setClock(UTCTime newTime)
|
|
|
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
|
|
* @fn esp32_getClock
|
|
|
|
|
|
*
|
|
|
|
|
|
* @brief Gets the current time. This will only return the seconds
|
|
|
|
|
|
* portion of time and doesn't include the factional second
|
|
|
|
|
|
* counter.
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param none
|
|
|
|
|
|
*
|
|
|
|
|
|
* @return number of seconds since 0 hrs, 0 minutes, 0 seconds,
|
|
|
|
|
|
* on the 1st of January 1900 UTC
|
|
|
|
|
|
*/
|
|
|
|
|
|
UTCTime esp32_getClock( void )
|
|
|
|
|
|
{
|
|
|
|
|
|
//time_t now;
|
|
|
|
|
|
|
|
|
|
|
|
return 0;//( now );
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
|
|
* @fn esp32_ConvertUTCTime
|
|
|
|
|
|
*
|
|
|
|
|
|
* @brief Converts UTCTime to UTCTimeStruct
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param tm - pointer to breakdown struct
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param secTime - number of seconds since 0 hrs, 0 minutes,
|
|
|
|
|
|
* 0 seconds, on the 1st of January 1900 UTC
|
|
|
|
|
|
*
|
|
|
|
|
|
* @return none
|
|
|
|
|
|
*/
|
|
|
|
|
|
void esp32_ConvertUTCTime( UTCTimeStruct *tm, UTCTime secTime )
|
|
|
|
|
|
{
|
|
|
|
|
|
// calculate the time less than a day - hours, minutes, seconds
|
|
|
|
|
|
{
|
|
|
|
|
|
uint32_t day = secTime % DAY;
|
|
|
|
|
|
tm->seconds = day % 60UL;
|
|
|
|
|
|
tm->minutes = (day % 3600UL) / 60UL;
|
|
|
|
|
|
tm->hour = day / 3600UL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Fill in the calendar - day, month, year
|
|
|
|
|
|
{
|
|
|
|
|
|
uint16_t numDays = secTime / DAY;
|
|
|
|
|
|
tm->year = BEGYEAR;
|
|
|
|
|
|
while ( numDays >= YearLength( tm->year ) )
|
|
|
|
|
|
{
|
|
|
|
|
|
numDays -= YearLength( tm->year );
|
|
|
|
|
|
tm->year++;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
tm->month = 0;
|
|
|
|
|
|
while ( numDays >= monthLength( IsLeapYear( tm->year ), tm->month ) )
|
|
|
|
|
|
{
|
|
|
|
|
|
numDays -= monthLength( IsLeapYear( tm->year ), tm->month );
|
|
|
|
|
|
tm->month++;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
tm->day = numDays;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
|
|
* @fn monthLength
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param lpyr - 1 for leap year, 0 if not
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param mon - 0 - 11 (jan - dec)
|
|
|
|
|
|
*
|
|
|
|
|
|
* @return number of days in specified month
|
|
|
|
|
|
*/
|
|
|
|
|
|
static uint8_t monthLength( uint8_t lpyr, uint8_t mon )
|
|
|
|
|
|
{
|
|
|
|
|
|
uint8_t days = 31;
|
|
|
|
|
|
|
|
|
|
|
|
if ( mon == 1 ) // feb
|
|
|
|
|
|
{
|
|
|
|
|
|
days = ( 28 + lpyr );
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if ( mon > 6 ) // aug-dec
|
|
|
|
|
|
{
|
|
|
|
|
|
mon--;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ( mon & 1 )
|
|
|
|
|
|
{
|
|
|
|
|
|
days = 30;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return ( days );
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
|
|
* @fn esp32_ConvertUTCSecs
|
|
|
|
|
|
*
|
|
|
|
|
|
* @brief Converts a UTCTimeStruct to UTCTime
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param tm - pointer to provided struct
|
|
|
|
|
|
*
|
|
|
|
|
|
* @return number of seconds since 00:00:00 on 01/01/1900 (UTC)
|
|
|
|
|
|
*/
|
|
|
|
|
|
UTCTime esp32_ConvertUTCSecs( UTCTimeStruct *tm )
|
|
|
|
|
|
{
|
|
|
|
|
|
uint32_t seconds;
|
|
|
|
|
|
|
|
|
|
|
|
/* Seconds for the partial day */
|
|
|
|
|
|
seconds = (((tm->hour * 60UL) + tm->minutes) * 60UL) + tm->seconds;
|
|
|
|
|
|
|
|
|
|
|
|
/* Account for previous complete days */
|
|
|
|
|
|
{
|
|
|
|
|
|
/* Start with complete days in current month */
|
|
|
|
|
|
uint16_t days = tm->day;
|
|
|
|
|
|
|
|
|
|
|
|
/* Next, complete months in current year */
|
|
|
|
|
|
{
|
|
|
|
|
|
int8_t month = tm->month;
|
|
|
|
|
|
while ( --month >= 0 )
|
|
|
|
|
|
{
|
|
|
|
|
|
days += monthLength( IsLeapYear( tm->year ), month );
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Next, complete years before current year */
|
|
|
|
|
|
{
|
|
|
|
|
|
uint16_t year = tm->year;
|
|
|
|
|
|
while ( --year >= BEGYEAR )
|
|
|
|
|
|
{
|
|
|
|
|
|
days += YearLength( year );
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Add total seconds before partial day */
|
|
|
|
|
|
seconds += (days * DAY);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return ( seconds );
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
|
|
* @fn esp32Timeinit
|
|
|
|
|
|
* @brief esp32 Time init
|
|
|
|
|
|
* @param None.
|
|
|
|
|
|
* @return None.
|
|
|
|
|
|
*/
|
|
|
|
|
|
void esp32TimeTask(void *pvParameters);
|
|
|
|
|
|
|
|
|
|
|
|
void esp32Timeinit(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
//创建任务
|
|
|
|
|
|
rt_thread_t esp32_thread = rt_thread_create("rtc", //名称
|
|
|
|
|
|
esp32TimeTask, //线程代码
|
|
|
|
|
|
RT_NULL, //参数
|
|
|
|
|
|
10240, //栈大小
|
|
|
|
|
|
12, //优先级
|
|
|
|
|
|
50); //时间片
|
|
|
|
|
|
if (esp32_thread != RT_NULL)
|
|
|
|
|
|
{
|
|
|
|
|
|
rt_thread_startup(esp32_thread); //线程进入就绪态
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
LOG_I("esp32_thread create failure\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
|
|
* @fn esp32TimeTask
|
|
|
|
|
|
* @brief Uses the free running rollover count of the MAC backoff timer;
|
|
|
|
|
|
* this timer runs freely with a constant 1s interval.
|
|
|
|
|
|
* This function is intended to be invoked
|
|
|
|
|
|
* from the background, not interrupt level.
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param None.
|
|
|
|
|
|
*
|
|
|
|
|
|
* @return None.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
//extern TaskHandle_t pvguiTaskTask;
|
|
|
|
|
|
|
|
|
|
|
|
void esp32TimeTask(void *pvParameters)
|
|
|
|
|
|
{
|
|
|
|
|
|
ZIGEvent evt;
|
|
|
|
|
|
|
|
|
|
|
|
LOG_I("esp32TimeTask running start");
|
|
|
|
|
|
|
|
|
|
|
|
while(1)
|
|
|
|
|
|
{
|
|
|
|
|
|
rt_thread_mdelay(1000);//1s
|
|
|
|
|
|
// //esp32_getClock();
|
|
|
|
|
|
|
|
|
|
|
|
// if((pvguiTaskTask)&&(eTaskGetState(pvguiTaskTask)!=eSuspended))//gui任务不是挂起状态 则定时刷新时间
|
|
|
|
|
|
// {
|
|
|
|
|
|
|
|
|
|
|
|
evt.event=ZIG_STATE_RTC_CURRENT;
|
|
|
|
|
|
evt.length=0;
|
|
|
|
|
|
evt.buffStr=NULL;
|
|
|
|
|
|
rt_mq_send(custom_rx_evt_queue,&evt, sizeof(ZIGEvent));//显示和动作操作
|
|
|
|
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
// else
|
|
|
|
|
|
// {
|
|
|
|
|
|
// ESP_LOGI(TAG,"pvguiTaskTask not running");
|
|
|
|
|
|
// }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|