134 lines
3.6 KiB
C
134 lines
3.6 KiB
C
#include "SNTP_ESP.h"
|
||
#include "esp_log.h"
|
||
#include "esp_sntp.h"
|
||
#include "freertos/FreeRTOS.h"
|
||
#include "freertos/task.h"
|
||
#include <sys/time.h>
|
||
#include <string.h>
|
||
|
||
#define TAG "SNTP_ESP"
|
||
|
||
static bool time_synced = false;
|
||
|
||
// 时间同步回调函数
|
||
static void sntp_sync_time_callback(struct timeval *tv)
|
||
{
|
||
time_t now = tv->tv_sec;
|
||
struct tm timeinfo;
|
||
localtime_r(&now, &timeinfo);
|
||
|
||
char time_str[64];
|
||
strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", &timeinfo);
|
||
|
||
ESP_LOGI(TAG, "时间同步成功: %s", time_str);
|
||
time_synced = true;
|
||
}
|
||
|
||
esp_err_t sntp_esp_set_timezone(void)
|
||
{
|
||
// 设置中国标准时间(北京时间)
|
||
setenv("TZ", "CST-8", 1);
|
||
tzset();
|
||
ESP_LOGI(TAG, "时区设置为北京时间 (CST-8)");
|
||
return ESP_OK;
|
||
}
|
||
|
||
time_t sntp_esp_get_current_time(void)
|
||
{
|
||
// 使用POSIX函数获取时间
|
||
return time(NULL);
|
||
}
|
||
|
||
void sntp_esp_print_current_time(void)
|
||
{
|
||
time_t now = sntp_esp_get_current_time();
|
||
struct tm timeinfo;
|
||
char buffer[64];
|
||
|
||
localtime_r(&now, &timeinfo);
|
||
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S %A", &timeinfo);
|
||
|
||
ESP_LOGI(TAG, "当前时间: %s", buffer);
|
||
}
|
||
|
||
esp_err_t sntp_esp_get_formatted_time(char *buffer, size_t size, const char *format)
|
||
{
|
||
if (buffer == NULL || format == NULL) {
|
||
return ESP_FAIL;
|
||
}
|
||
|
||
time_t now = sntp_esp_get_current_time();
|
||
struct tm timeinfo;
|
||
localtime_r(&now, &timeinfo);
|
||
|
||
strftime(buffer, size, format, &timeinfo);
|
||
return ESP_OK;
|
||
}
|
||
|
||
bool sntp_esp_is_synced(void)
|
||
{
|
||
time_t now = time(NULL);
|
||
// 检查时间是否已初始化(从1970年到现在)
|
||
return (now > 1000000000); // 2001年9月9日之后的任何时间都认为是有效时间
|
||
}
|
||
|
||
bool sntp_esp_wait_sync(uint32_t max_wait_ms)
|
||
{
|
||
ESP_LOGI(TAG, "等待时间同步(最长等待 %lu ms)...", (unsigned long)max_wait_ms);
|
||
|
||
uint32_t start_time = xTaskGetTickCount();
|
||
uint32_t max_wait_ticks = pdMS_TO_TICKS(max_wait_ms);
|
||
|
||
while ((xTaskGetTickCount() - start_time) < max_wait_ticks) {
|
||
if (sntp_esp_is_synced()) {
|
||
ESP_LOGI(TAG, "时间同步完成");
|
||
return true;
|
||
}
|
||
vTaskDelay(pdMS_TO_TICKS(100)); // 每100毫秒检查一次
|
||
}
|
||
|
||
ESP_LOGW(TAG, "时间同步超时");
|
||
return false;
|
||
}
|
||
|
||
esp_err_t sntp_esp_init(void)
|
||
{
|
||
ESP_LOGI(TAG, "初始化SNTP服务");
|
||
|
||
// 重置同步标志
|
||
time_synced = false;
|
||
|
||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||
// 设置时间服务器(默认使用 pool.ntp.org)
|
||
esp_sntp_setoperatingmode(SNTP_OPMODE_POLL);
|
||
|
||
// 添加 NTP 服务器
|
||
// esp_sntp_setservername(0, "pool.ntp.org"); // 默认服务器
|
||
esp_sntp_setservername(0, "cn.pool.ntp.org"); // 中国 NTP 服务器
|
||
esp_sntp_setservername(1, "ntp1.aliyun.com"); // 阿里云 NTP 服务器
|
||
esp_sntp_setservername(2, "ntp.tencent.com"); // 腾讯云 NTP 服务器
|
||
|
||
// 设置时间同步回调
|
||
esp_sntp_set_time_sync_notification_cb(sntp_sync_time_callback);
|
||
|
||
// 初始化 SNTP
|
||
esp_sntp_init();
|
||
#else
|
||
sntp_setoperatingmode(SNTP_OPMODE_POLL);
|
||
|
||
// esp_sntp_setservername(0, "pool.ntp.org"); // 默认服务器
|
||
sntp_setservername(0, "cn.pool.ntp.org"); // 中国 NTP 服务器
|
||
sntp_setservername(1, "ntp1.aliyun.com"); // 阿里云 NTP 服务器
|
||
sntp_setservername(2, "ntp.tencent.com"); // 腾讯云 NTP 服务器
|
||
|
||
sntp_set_time_sync_notification_cb(sntp_sync_time_callback);
|
||
sntp_init(); // 初始化 SNTP
|
||
#endif
|
||
|
||
sntp_esp_set_timezone(); // 设置时区
|
||
sntp_esp_print_current_time(); // 打印时间
|
||
|
||
ESP_LOGI(TAG, "SNTP服务初始化完成");
|
||
return ESP_OK;
|
||
}
|