#include "SNTP_ESP.h" #include "esp_log.h" #include "esp_sntp.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include #include #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; }