一、背景知识
【1】什么是NTP服务器?
NTP是网络时间协议(Network Time Protocol,简称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
【2】RTC实时时钟是什么?
RTC (Real-Time Clock)实时时钟,是指一种专门用于记忆日期、时间的计时芯片或模块。一般包括一个时钟芯片、一块石英晶体、一块温度补偿电路、电源管理电路等组成。RTC可以精确地记录日期和时间,即使是在断电等异常情况下,也能保持记录的时间长达数年。常常用于嵌入式系统、数据采集设备等领域,是一种至关重要的设备。在某些系统应用中,RTC也会成为其他设备的时钟源,如单片机或微控制器单位等。
RTC的时间精度通常为ppm 级别,即每百万分之一,能够满足大多数实时应用场景的要求。为了提高RTC的稳定度和精度,许多RTC都带有自动校正功能,可以自动从外部时钟源或NTP服务器中获取准确的时间,并进行校正。同时,许多RTC还会集成电源管理功能,支持低功耗模式以延长电池寿命。
二、ESP8266获取网络时间
要通过ESP8266联网并获取网络时间,需要执行以下步骤:
- 在STM32F103ZET6上配置UART串口以与ESP8266进行通信。
- 使用AT指令将ESP8266连接到Wi-Fi网络。可以使用以下指令:
AT+CWJAP="SSID","password"
其中,替换 “SSID” 为自己的Wi-Fi网络名称,”password” 是Wi-Fi密码。
- 使用AT指令连接到NTP服务器并获取时间。您可以使用以下指令:
AT+CIPSNTPCFG=0,1,"pool.ntp.org"
AT+CIPSNTPTIME?
这将连接到ntp服务器并检索当前的UTC时间。
- 将ESP8266返回的UTC时间转换为本地时间。您需要知道您所在的时区,并对UTC进行适当的调整。
- 将本地时间设置为STM32F103ZET6上的RTC实时时钟。
下面是一个示例代码
#include
#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) 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时间和日期
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) { // 做其他的事情... } }
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
什么是栈 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。 压栈:栈的插入操作叫做进栈/压栈/入栈,入数据…