Foreword
In the previous chapter, we used the development board to perform a ping test. In this chapter, we use it to obtain the network time through SNTP and display it on the serial port.
What is SNTP? What can it be used for?
SNTP (Simple Network Time Protocol) is a protocol used to synchronize time across a wide area network or a local area network. It has high accuracy (tens of milliseconds). SNTP is a simplified version of the NTP protocol; we can use it to synchronize time with local devices. Correction time.
SNTP message
The NTP message format is shown in the figure above, and its field meanings are as follows:
- LI leap second identifier, occupying 2 bits
- VN version number, occupies 3 bits, indicating the NTP version number, currently 3
- Mode mode, occupies 3 bits, indicating the mode
- stratum (layer), occupying 8 bits
- Poll test interval, occupies 8 bits, indicating the maximum interval between continuous information
- Precision precision, occupies 8 bits, indicating the accuracy of the local clock
- Root Delay, which occupies 8 bits, represents the total round-trip delay between the main reference sources.
- Root Dispersion is root discrete, occupying 8 bits, indicating nominal errors related to the main reference source
- Reference Identifier reference clock identifier, occupies 8 bits, used to identify special reference sources
- Reference timestamp, 64bits timestamp, the latest time when the local clock was modified.
- Original timestamp, the time sent by the client, 64bits.
- Accept timestamp, the time received by the server, 64bits.
- Transmit timestamp, the time when the server sends the response, 64bits.
- Authenticator (optional)
Connection method
Connect to the LAN port of the router with Internet access
Get network time test
1. Related code
We open the library file and find the SNTP folder. Open the sntp.c file. In this chapter, we directly call these functions: SNTP_init(), SNTP_run(), one is initialization and the other is running; we pass in the initialization functions in sequence. Socket port number, NTP server IP address, time zone (directly in the sntp.c file, you can see that China corresponds to 39), data sending and receiving cache buf; when running the function, we can pass in the corresponding time structure, as shown below:
void SNTP_init(uint8_t s, uint8_t *ntp_server, uint8_t tz, uint8_t *buf) { NTP_SOCKET = s; NTPformat.dstaddr[0] = ntp_server[0]; NTPformat.dstaddr[1] = ntp_server[1]; NTPformat.dstaddr[2] = ntp_server[2]; NTPformat.dstaddr[3] = ntp_server[3]; time_zone = tz; data_buf = buf; uint8_t Flag; NTPformat.leap = 0; /* leap indicator */ NTPformat.version = 4; /* version number */ NTPformat.mode = 3; /* mode */ NTPformat.stratum = 0; /* stratum */ NTPformat.poll = 0; /* poll interval */ NTPformat.precision = 0; /* precision */ NTPformat.rootdelay = 0; /* root delay */ NTPformat.rootdisp = 0; /* root dispersion */ NTPformat.refid = 0; /* reference ID */ NTPformat.reftime = 0; /* reference time */ NTPformat.org = 0; /* origin timestamp */ NTPformat.rec = 0; /* receive timestamp */ NTPformat.xmt = 1; /* transmit timestamp */ Flag = (NTPformat.leap<<6) + (NTPformat.version<<3) + NTPformat.mode; //one byte Flag memcpy(ntpmessage,(void const*)( & amp;Flag),1); } int8_t SNTP_run(datetime *time) { uint16_t RSR_len; uint32_t destip = 0; uint16_t destport; uint16_t startindex = 40; //last 8-byte of data_buf[size is 48 byte] is xmt, so the startindex should be 40 switch(getSn_SR(NTP_SOCKET)) { case SOCK_UDP: if ((RSR_len = getSn_RX_RSR(NTP_SOCKET)) > 0) { if (RSR_len > MAX_SNTP_BUF_SIZE) RSR_len = MAX_SNTP_BUF_SIZE; // if Rx data size is lager than TX_RX_MAX_BUF_SIZE recvfrom(NTP_SOCKET, data_buf, RSR_len, (uint8_t *) & amp;destip, & amp;destport); \t\t\t get_seconds_from_ntp_server(data_buf,startindex); time->yy = Nowdatetime.yy; time->mo = Nowdatetime.mo; time->dd = Nowdatetime.dd; time->hh = Nowdatetime.hh; time->mm = Nowdatetime.mm; time->ss = Nowdatetime.ss; ntp_retry_cnt=0; //close(NTP_SOCKET); //return 1; } if(ntp_retry_cnt<0xFFFF) { if(ntp_retry_cnt==0)//first send request, no need to wait { sendto(NTP_SOCKET,ntpmessage,sizeof(ntpmessage),NTPformat.dstaddr,ntp_port); ntp_retry_cnt + + ; } else // send request again? it should wait for a while { if((ntp_retry_cnt % 0xFFF) == 0) //wait time { sendto(NTP_SOCKET,ntpmessage,sizeof(ntpmessage),NTPformat.dstaddr,ntp_port); #ifdef _SNTP_DEBUG_ printf("ntp retry: %d\r\ ", ntp_retry_cnt); #endif ntp_retry_cnt + + ; return 1; } } } else //ntp retry fail { ntp_retry_cnt=0; #ifdef _SNTP_DEBUG_ printf("ntp retry failed!\r\ "); #endif close(NTP_SOCKET); } break; case SOCK_CLOSED: socket(NTP_SOCKET,Sn_MR_UDP,ntp_port,0); break; } // Return value // 0 - failed / 1 - success return 0; }
The main function is relatively simple. We directly initialize the parameters corresponding to the network configuration information and the NTP server IP address; then initialize sntp and call it in the loop, as shown below:
#define SOCKET_ID 0 #define ETHERNET_BUF_MAX_SIZE (1024 * 2) void network_init(void); wiz_NetInfo net_info = { .mac = {0x00, 0x08, 0xdc, 0x16, 0xed, 0x2e}, .ip = {192, 168, 1, 11}, .sn = {255, 255, 255, 0}, .gw = {192, 168, 1, 1}, .dns = {8, 8, 8, 8}, .dhcp = NETINFO_STATIC}; wiz_NetInfo get_info; static uint8_t ethernet_buf[ETHERNET_BUF_MAX_SIZE] = {0,}; static uint8_t sntp_server_ip[4]={202, 112, 10, 60}; static uint16_t timezone = 39; datetime date; int main() { stdio_init_all(); sleep_ms(2000); network_init(); SNTP_init(SOCKET_ID, sntp_server_ip, timezone, ethernet_buf); while(true) { SNTP_run( & amp;date); sleep_ms(1000); printf("NOW: %d-%d-%d %d:%d:%d\r\ ",date.yy,date.mo,date.dd,date.hh,date.mm,date.ss ); } } void network_init(void) { uint8_t temp; wizchip_initialize(); printf("W5100s udp client example.\r\ "); sleep_ms(2000); wizchip_setnetinfo( & amp;net_info); print_network_information(get_info); sleep_ms(2000); }
2. Test phenomenon
After compilation and burning, open the serial monitor and you can see the real-time time information printed. The first two times printed are 0 because the socket port is not opened and the time is not obtained during the two states before the first request is sent after it is opened. data, so what is printed is the 0 assigned by the initialization, as shown in the following figure:
Related links
Related routine links in this chapterhttps://gitee.com/wiznet-hk/w5100s-evb-pico-routine.git