NTP — это протокол сетевого времени (сокращенно NTP), который представляет собой протокол, используемый для синхронизации компьютерного времени. NTP-сервер — это компьютер или устройство, предоставляющее услуги NTP. Основная функция NTP-сервера — обеспечить синхронизацию времени всех устройств в сети, чтобы время между каждым устройством соответствовало друг другу. Серверы NTP обычно подключаются к устройствам с высокоточными источниками времени, такими как приемники GPS или атомные часы, чтобы обеспечить согласованную и точную доставку времени. Компьютеры в сети могут синхронизировать свое время, подключаясь к NTP-серверу, и гарантировать, что они работают в один и тот же момент.
Существует множество NTP-серверов, которые можно использовать. Ниже приведен список некоторых часто используемых NTP-серверов:
1. cn.ntp.org.cn
2. ntp.sjtu.edu.cn
3. ntp.linux.org.cn
4. time.nist.gov.cn
5. ntp.aliyun.com
6. ntp.api.bz
7. ntp1.aliyun.com
8. time1.cloud.tencent.com
9. pool.ntp.org.cn
RTC (часы реального времени) — это чип или модуль синхронизации, специально используемый для запоминания даты и времени. Обычно он включает в себя тактовый чип, кварцевый кристалл, схему температурной компенсации, схему управления питанием и т. д. RTC может точно записывать дату и время и хранить записи в течение нескольких лет даже в аномальных условиях, таких как перебои в подаче электроэнергии. Это жизненно важное устройство, которое часто используется во встроенных системах, оборудовании для сбора данных и других областях. В некоторых системных приложениях RTC также становится источником синхронизации для других устройств, таких как микроконтроллеры или блоки микроконтроллеров.
Точность времени RTC обычно находится на уровне ppm, то есть одной части на миллион, что может удовлетворить требования большинства сценариев приложений реального времени. Чтобы повысить стабильность и точность часов реального времени, многие часы реального времени оснащены функцией автоматической коррекции, которая может автоматически получать точное время от внешнего источника часов или сервера NTP и выполнять коррекции. В то же время многие RTC также будут интегрировать функции управления питанием и поддерживать режимы низкого энергопотребления для продления срока службы батареи.
Чтобы подключиться к Интернету через ESP8266 и получить время сети, необходимо выполнить следующие действия:
AT+CWJAP="SSID","password"
Среди них замените «SSID» на имя вашей собственной сети Wi-Fi, а «пароль» — это пароль Wi-Fi.
AT+CIPSNTPCFG=0,1,"pool.ntp.org"
AT+CIPSNTPTIME?
Это позволит подключиться к ntp-серверу и получить текущее время UTC.
Ниже приведен пример кода
#include <stdio.h>
#include "stm32f10x.h"
// Конфигурация UART
void uart_init() {
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
}
// Отправьте AT-команду и дождитесь ответа
int send_at_command(char* command, char* response, uint32_t timeout) {
// Отправить команду
USART_SendData(USART1, (uint8_t*)command, strlen(command));
// Ожидание ответа
uint32_t start_time = HAL_GetTick();
while ((HAL_GetTick() - start_time) < timeout) {
if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != RESET) {
char c = USART_ReceiveData(USART1);
// Проверьте, получен ли ожидаемый ответ
if (strstr(response, c) != NULL) {
return 0; // успех
}
}
}
return -1; // Время ожидания истекло или не получен ожидаемый ответ
}
// соединятьESP8266приезжатьWi-Fivoid connect_to_wifi() {
char command[50];
char response[100];
// Настроить Wi-Fi SSID и пароль
sprintf(command, "AT+CWJAP=\"%s\",\"%s\"\r\n", "YourSSID", "YourPassword");
send_at_command(command, "OK", 5000);
}
// подключиться к NTP-серверу и получить время
int get_ntp_time(uint32_t* time) {
char response[100];
// Настроить SNTP-клиент
send_at_command("AT+CIPSNTPCFG=0,1,\"pool.ntp.org\"\r\n", "OK", 5000);
// Получить время
send_at_command("AT+CIPSNTPTIME?\r\n", response, 5000);
// Проанализируйте ответ и извлеките временную метку
char* token = strtok(response, ",");
uint32_t timestamp = atoi(token);
*time = timestamp - 2208988800UL; // Преобразование в временную метку Unix
return 0;
}
// Установите время на RTC
void set_rtc_time(uint32_t time) {
// Включите тактовую частоту периферийных устройств PWR и BKP.
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
// Разблокируйте область резервного реестра
PWR_BackupAccessCmd(ENABLE);
// Настроить часы реального времени
RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div128); // Источник часов RTC: HSE/128.
RCC_RTCCLKCmd(ENABLE); // Включить часы RTC
RTC_InitTypeDef RTC_InitStructure;
// Настроить часы реального часы времени
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24; RTC_InitStructure.RTC_AsynchPrediv = 127;
RTC_InitStructure.RTC_SynchPrediv = 255;
RTC_Init(&RTC_InitStructure);
// Установите время RTC
RTC_TimeTypeDef RTC_TimeStruct;
RTC_DateTypeDef RTC_DateStruct;
// Преобразовать временную метку Unix в время и дату RTC
uint32_t days = time / 86400;
uint32_t seconds = time % 86400;
uint32_t hours = seconds / 3600;
uint32_t minutes = (seconds % 3600) / 60;
uint32_t secs = (seconds % 3600) % 60;
uint32_t year = 1970;
uint32_t month = 1;
while (days > 365) { if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) { days -= 366; } else { days -= 365; } year++; }
while (days > 0) { if (month == 2)
{ if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) { if (days > 29) { days -= 29; } else { break; } } else { if (days > 28) { days -= 28; } else { break; } } } else if (month == 4 || month == 6 || month == 9 || month == 11) { if (days > 30) { days -= 30; } else { break; } } else { if (days > 31) { days -= 31; } else { break; } } month++; if (month > 12) { month = 1; year++; } }
RTC_TimeStruct.RTC_Hours = hours; RTC_TimeStruct.RTC_Minutes = minutes; RTC_TimeStruct.RTC_Seconds = secs; RTC_DateStruct.RTC_Date = days; RTC_DateStruct.RTC_Month = month; RTC_DateStruct.RTC_Year = year - 2000;
// Установите время Часы реального времени и дата
RTC_SetTime(RTC_Format_BIN, &RTC_TimeStruct);
RTC_SetDate(RTC_Format_BIN, &RTC_DateStruct); }
int main()
{
// Инициализируйте последовательный порт UART
uart_init();
// соединятьESP8266приезжатьWi-Fi connect_to_wifi();
// Получить время NTP
uint32_t ntp_time; get_ntp_time(&ntp_time);
// Установите время, чтобы
RTC set_rtc_time(ntp_time);
while (1) { // Занимайтесь другими делами... } }