[MM32硬件] 【EV Board (MM32L0136C7P)测评】基于NTP对时的互联网时钟

[复制链接]
1562|9
 楼主| HonestQiao 发表于 2022-12-6 11:14 | 显示全部楼层 |阅读模式
本帖最后由 HonestQiao 于 2022-12-6 11:47 编辑

#申请原创# 一、想法起源
之前使用ESP32+OLED(SSD1306)只做过基于NTP对时的互联网时钟,无需RTC,也不需要对时,效果非常好。MM32L0136C7P开发板上自带了SLCD,其上有两个数字显示区域,用来做时钟显示,再合适不过了。
65138638e9ab56b4fa.png
在官方最新的演示代码中,只有SLCD各笔画的统一显示测试。
后经过坛友分享,拿到了MM32L0130_LibSamples_V020_1201.zip,其中有SCLD数字和单位符号显示的实例。

经过一番研究后,将ESP8266与MM32L0136C7P相结合,实现了如下的电子时钟:
18038638e9bc3e487b.png

二、实现规划
查找资料的时候,看到有大佬在MM32上,实现了ESP8266的透传,非常的厉害。
不过我这个应用,就是简单的进行NTP对时即可。
所以NTP对时这个部分,就让ESP8266自己完成就好了。
ESP8266对时后,通过串口,每秒钟,自动上报一次当前时间数据。

MM32L0136C7P开发板则通过串口,来获取ESP8266提供的时间信息。
为了确保处理效率更好,经过研究学习例子,最终使用中断的方式,来进行数据的接收,效率更高。

最后,为了整体显示效果更好,把MM32L0136C7P开发板上的4个LED都利用起来了,根据时间信息中当前秒的个位数,来决定LED的显示,这样就活了起来。

具体规的功能:
1. 由ESP8266直接联网,进行NTP对时,然后通过串口发送时间信息,发送数据的格式为:Tyyyy-mm-dd HH:MM:SS XX,其中XX为CRC8校验码
2. MM32L0136C7P开发板通过串口获取时间信息,进行解析,然后显示到SLCD屏幕上。
3. MM32L0136C7P开发板取秒数中的第0、1、2、3bit位,该n位为1,则点亮对应的LDn

三、硬件物料


1. ESP8266-S1

ESP32一般都要大一点点,而ESP8266-01则较为较小,所示使用了一块ESP8266-01来提供网络对时功能。
82743638e9c64c1d37.png

为了方便烧录,我还有一个ESP8266-01的底座:
12896638e9c8440aaf.png
把ESP8266-01插上底座,就可以直接接到电脑上,进行固件下载烧录了。

另外,ESP8266-01正常运行时,需要CH_PD高电平使能,通常是直接VCC:
68992638e9d72c8b43.png
所以,直接在ESP8266-01上面,在VCC和CH_PD引脚上,焊了一个跳线,刚好用MM32L0136C7P开发板上的UART1的跳线帽:
32149638e9dd41da34.png

2、MM32L0136C7P开发板
参考原理图,以及演示代码,使用UART1来进行和ESP8266-01进行通讯,所对应的引脚选用PA9、PA10
32520638ea0ca17117.png


为了稳固,把ESP8266-01开发板,直接用胶枪给沾到了MM32L0136C7P开发板右上角:
52651638ea1bee1f2c.png

具体接线,就在ESP8266-01背后偷偷进行了:
87336638ea2630da72.png
不过MM32L0136C7P开发板的接线只能在正面进行。

四、软件设计
软件部分,分为两个部分,一个是ESP8266上面的NTP对时和事件信息提供,一个是MM32L0136C7P开发板上的主逻辑。

1. ESP8266部分
简单起见,使用了Arduino IDE进行开发,且还提供了相应的实例。
具体代码如下:
  1. /*
  2. * ESP8266_NTP_Time_Clock.ino
  3. * NTP Time Clock at ESP8266
  4. *
  5. */

  6. #include <TimeLib.h>
  7. #include <ESP8266WiFiMulti.h>
  8. #include <WiFiUdp.h>

  9. #define DEBUG_MODE 0

  10. ESP8266WiFiMulti wifiMulti;
  11. // WiFi connect timeout per AP. Increase when connecting takes longer.
  12. const uint32_t connectTimeoutMs = 5000;

  13. const char ssid[] = "OpenBSD";  //  your network SSID (name)
  14. const char pass[] = "********";       // your network password

  15. // NTP Servers:
  16. static const char ntpServerName[] = "ntp.aliyun.com";

  17. // TimeZone
  18. const int timeZone = 8;     // CST +8


  19. WiFiUDP Udp;
  20. unsigned int localPort = 8888;  // local port to listen for UDP packets

  21. static const uint8_t crc_table[] = {
  22.     0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, 0x38, 0x3f, 0x36, 0x31,
  23.     0x24, 0x23, 0x2a, 0x2d, 0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65,
  24.     0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d, 0xe0, 0xe7, 0xee, 0xe9,
  25.     0xfc, 0xfb, 0xf2, 0xf5, 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd,
  26.     0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85, 0xa8, 0xaf, 0xa6, 0xa1,
  27.     0xb4, 0xb3, 0xba, 0xbd, 0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2,
  28.     0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea, 0xb7, 0xb0, 0xb9, 0xbe,
  29.     0xab, 0xac, 0xa5, 0xa2, 0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a,
  30.     0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32, 0x1f, 0x18, 0x11, 0x16,
  31.     0x03, 0x04, 0x0d, 0x0a, 0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42,
  32.     0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a, 0x89, 0x8e, 0x87, 0x80,
  33.     0x95, 0x92, 0x9b, 0x9c, 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4,
  34.     0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec, 0xc1, 0xc6, 0xcf, 0xc8,
  35.     0xdd, 0xda, 0xd3, 0xd4, 0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c,
  36.     0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44, 0x19, 0x1e, 0x17, 0x10,
  37.     0x05, 0x02, 0x0b, 0x0c, 0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34,
  38.     0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b, 0x76, 0x71, 0x78, 0x7f,
  39.     0x6a, 0x6d, 0x64, 0x63, 0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b,
  40.     0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13, 0xae, 0xa9, 0xa0, 0xa7,
  41.     0xb2, 0xb5, 0xbc, 0xbb, 0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83,
  42.     0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb, 0xe6, 0xe1, 0xe8, 0xef,
  43.     0xfa, 0xfd, 0xf4, 0xf3
  44. };

  45. time_t getNtpTime();
  46. void digitalClockDisplay();
  47. void printDigits(int digits);
  48. void sendNTPpacket(IPAddress &address);
  49. uint8_t crc8(uint8_t *p, uint8_t len);

  50. void setup()
  51. {
  52.   WiFi.persistent(false);

  53.   Serial.begin(115200);
  54.   while (!Serial) ; // Needed for Leonardo only

  55.   delay(250);
  56.   Serial.println("I:ESP8266 NTP Time Clock");
  57.   Serial.print("I:Connecting to ");
  58.   Serial.println(ssid);

  59.   // WiFi.begin(ssid, pass);
  60.   // while (WiFi.status() != WL_CONNECTED) {
  61.   //   delay(500);
  62.   //   Serial.print(".");
  63.   // }

  64.   WiFi.mode(WIFI_STA);
  65.   wifiMulti.addAP("OpenBSD", "13581882013");
  66.   while (wifiMulti.run(connectTimeoutMs) != WL_CONNECTED) {
  67.     delay(500);   
  68.     Serial.print(".");
  69.   }
  70.   Serial.println("OK");

  71.   Serial.print("I:IP address is ");
  72.   Serial.println(WiFi.localIP());
  73.   Serial.println("I:Starting UDP");
  74.   Udp.begin(localPort);
  75.   Serial.print("I:Local port: ");
  76.   Serial.println(Udp.localPort());
  77.   Serial.println("I:waiting for sync");
  78.   setSyncProvider(getNtpTime);
  79.   setSyncInterval(300);
  80. }

  81. time_t prevDisplay = 0; // when the digital clock was displayed

  82. void loop()
  83. {
  84.   if (timeStatus() != timeNotSet) {
  85.     if (now() != prevDisplay) { //update the display only if time has changed
  86.       prevDisplay = now();
  87.       digitalClockDisplay();
  88.     }
  89.   }
  90. }

  91. uint8_t crc8(char *p, uint8_t len)
  92. {
  93.         uint16_t i;
  94.         uint16_t crc = 0x0;

  95.         while (len--) {
  96.                 i = (crc ^ *p++) & 0xFF;
  97.                 crc = (crc_table[i] ^ (crc << 8)) & 0xFF;
  98.         }

  99.         return crc & 0xFF;
  100. }

  101. void digitalClockDisplay()
  102. {
  103.   // digital clock display of the time
  104.   // Serial.print(hour());
  105.   // printDigits(minute());
  106.   // printDigits(second());
  107.   // Serial.print(" ");
  108.   // Serial.print(day());
  109.   // Serial.print(".");
  110.   // Serial.print(month());
  111.   // Serial.print(".");
  112.   // Serial.print(year());
  113.   // Serial.println();
  114.   char timeStr[25] = {0};
  115.   sprintf(timeStr, "T:%04d-%02d-%02d %02d:%02d:%02d ", year(), month(), day(), hour(), minute(), second());
  116.   // Serial.println(timeStr);

  117.   uint8_t crc = crc8(timeStr, strlen(timeStr));
  118.   sprintf(timeStr, "%s%02X", timeStr, crc);
  119.   Serial.println(timeStr);
  120. }

  121. void printDigits(int digits)
  122. {
  123.   // utility for digital clock display: prints preceding colon and leading 0
  124.   Serial.print(":");
  125.   if (digits < 10)
  126.     Serial.print('0');
  127.   Serial.print(digits);
  128. }

  129. /*-------- NTP code ----------*/

  130. const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
  131. byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets

  132. time_t getNtpTime()
  133. {
  134.   IPAddress ntpServerIP; // NTP server's ip address

  135.   while (Udp.parsePacket() > 0) ; // discard any previously received packets
  136.   Serial.println("I:Transmit NTP Request");
  137.   // get a random server from the pool
  138.   WiFi.hostByName(ntpServerName, ntpServerIP);
  139.   Serial.print("I:");
  140.   Serial.print(ntpServerName);
  141.   Serial.print(": ");
  142.   Serial.println(ntpServerIP);
  143.   sendNTPpacket(ntpServerIP);
  144.   uint32_t beginWait = millis();
  145.   while (millis() - beginWait < 1500) {
  146.     int size = Udp.parsePacket();
  147.     if (size >= NTP_PACKET_SIZE) {
  148.       Serial.println("I:Receive NTP Response");
  149.       Udp.read(packetBuffer, NTP_PACKET_SIZE);  // read packet into the buffer
  150.       unsigned long secsSince1900;
  151.       // convert four bytes starting at location 40 to a long integer
  152.       secsSince1900 =  (unsigned long)packetBuffer[40] << 24;
  153.       secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
  154.       secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
  155.       secsSince1900 |= (unsigned long)packetBuffer[43];
  156.       return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
  157.     }
  158.   }
  159.   Serial.println("E:No NTP Response :-(");
  160.   return 0; // return 0 if unable to get the time
  161. }

  162. // send an NTP request to the time server at the given address
  163. void sendNTPpacket(IPAddress &address)
  164. {
  165.   // set all bytes in the buffer to 0
  166.   memset(packetBuffer, 0, NTP_PACKET_SIZE);
  167.   // Initialize values needed to form NTP request
  168.   // (see URL above for details on the packets)
  169.   packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  170.   packetBuffer[1] = 0;     // Stratum, or type of clock
  171.   packetBuffer[2] = 6;     // Polling Interval
  172.   packetBuffer[3] = 0xEC;  // Peer Clock Precision
  173.   // 8 bytes of zero for Root Delay & Root Dispersion
  174.   packetBuffer[12] = 49;
  175.   packetBuffer[13] = 0x4E;
  176.   packetBuffer[14] = 49;
  177.   packetBuffer[15] = 52;
  178.   // all NTP fields have been given values, now
  179.   // you can send a packet requesting a timestamp:
  180.   Udp.beginPacket(address, 123); //NTP requests are to port 123
  181.   Udp.write(packetBuffer, NTP_PACKET_SIZE);
  182.   Udp.endPacket();
  183. }


该部分的代码,参考了Arduino IDE的8266例子中的:
25946638ea37297bc7.png

在此基础上,进行了一些小的修改:
  • 将WiFi连接部分,修改为了WiFiMul,这样就可以同时设置多组WiFi连接,更方便使用。
  • 添加了查表计算CRC8的代码,以便接收端收到后进行校验,确保数据准确。不过,MM32L0136C7P不分,我没有使用到,大家有需要可以在接收后进行校验。
  • 修改了信息的输出,正常信息使用I:开头,错误信息使用E:开头,时间信息使用T:开头,方便接收端进行解析


将以上代码烧录到ESP8266,然后打开串口终端,就可以收到启动的信息,以及时间信息:
62346638ea469761b1.png

测试验证完成,就可以连到MM32L0136C7P开发板上使用了。

2. MM32L0136C7P开发板
该部分的代码,参考了SLCD_ShowOnStop、UART_Tx_DMA_Interrupt_Rx_Interrupt。
UART_Tx_DMA_Interrupt_Rx_Interrupt实例,提供了中断收发数据的演示,基本不用修改,连引脚定义都是对应的,直接就可以使用了。
SLCD_ShowOnStop,则提供了显示数字和单位符号的演示,其中关键的调用如下:
  • LCD_Clear():清屏
  • LCD_DisplayNumber1(索引, '字符', 小数点标志):大号数字区域显示
  • LCD_DisplayNumber2(索引, '字符', 小数点标志):小号数字区域显示
  • LCD_DisplayUnit(索引, 显示标志):单位符号显示


大号数字显示:LCD_DisplayNumber1(索引, '字符', 小数点标志)
索引对应如下:
24885638ea63c6060d.png

字符对应如下:
78768638ea69e1c399.png
从上表中可知,除了0-9,还能显示一部分字母,但是不全,例如没有K,因为没法显示区分。

小数点标志,就表示是否显示小数点,0-不显示,1-显示


小号数字显示:LCD_DisplayNumber2(索引, '字符', 小数点标志)
索引对应如下:
43206638ea78344db2.png

小号区域的显示字符,演示代码只有0-9。当然,可以根据自己的需要进行扩展。
小数点标志和大号区域相同。


单位符号显示:LCD_DisplayUnit(索引, 显示标志)
索引有10个,对应下图:
{"S1 ", "S2 ", "S3 ", "S4 ", "S9 ", "T1 ", "W1 ", "C1 ", "C2 ", "C3 "};
89755638eb5e4de2f3.png

时钟部分,要显示的:,使用的就是C2、C3,索引为8、9

最终,main.c的代码如下:
  1. ////////////////////////////////////////////////////////////////////////////////
  2. /// [url=home.php?mod=space&uid=288409]@file[/url]    main.c
  3. /// [url=home.php?mod=space&uid=187600]@author[/url]  AE TEAM
  4. /// [url=home.php?mod=space&uid=247401]@brief[/url]   THIS FILE PROVIDES ALL THE SYSTEM FUNCTIONS.
  5. ////////////////////////////////////////////////////////////////////////////////

  6. // Define to prevent recursive inclusion
  7. #define _MAIN_C_

  8. // Files includes

  9. #include "delay.h"
  10. #include "slcd.h"
  11. #include "led.h"
  12. #include "uart_txdma_rx_interrupt.h"

  13. ////////////////////////////////////////////////////////////////////////////////
  14. /// @addtogroup MM32_Example_Layer
  15. /// @{

  16. ////////////////////////////////////////////////////////////////////////////////
  17. /// @addtogroup MAIN
  18. /// @{

  19. ////////////////////////////////////////////////////////////////////////////////
  20. /// @addtogroup MAIN_Exported_Constants
  21. /// @{
  22. #define        GET_BIT(x, bit)        ((x & (1 << bit)) >> bit)        /* 获取第bit位 */

  23. #define APP_TITLE "I:MM32 NTP Net Clock\r\n"

  24. u8 gSendBuf[] = "I:yyyy-mm-dd HH:MM:SS\r\n";

  25. ////////////////////////////////////////////////////////////////////////////////
  26. /// [url=home.php?mod=space&uid=247401]@brief[/url]  This function is main entrance.
  27. /// @param  None.
  28. /// @retval  0.
  29. ////////////////////////////////////////////////////////////////////////////////
  30. s32 main(void)
  31. {
  32.     u8 len;
  33.     u16 times = 0;
  34.    
  35.     u16 year;
  36.     u8 month,day,hour,minute,second;
  37.     u8 crc;
  38.     u8 buf[25] = {0};
  39.    
  40.     DELAY_Init();
  41.     LED_Init();
  42.     DELAY_Ms(100);
  43.     //slcd_test();
  44.     slcd_init();

  45.    
  46.     UART1_NVIC_Init(115200);
  47.     NVIC_Configure(DMA1_Channel2_3_IRQn, 2, 0);

  48.     UART1_SendString(APP_TITLE);
  49.     DMA_NVIC_Send_Config(DMA1_Channel2, (u32)&UART1->TDR, (u32)gSendBuf, sizeof(gSendBuf)/sizeof(gSendBuf[0]));
  50.    
  51.     LCD_Clear();
  52.    
  53.     LCD_DisplayNumber2(0, '2', 0);
  54.     LCD_DisplayNumber2(1, '0', 0);
  55.     LCD_DisplayNumber2(2, '2', 0);
  56.     LCD_DisplayNumber2(3, '2', 0);


  57.     LCD_DisplayNumber1(0, '-', 0);
  58.     LCD_DisplayNumber1(1, 'C', 0);
  59.     LCD_DisplayNumber1(2, 'l', 0);
  60.     LCD_DisplayNumber1(3, 'o', 0);
  61.     LCD_DisplayNumber1(4, 'c', 0);
  62.     LCD_DisplayNumber1(5, 'L', 0);
  63.    
  64.     DELAY_Ms(5000);
  65.                
  66.     while(1) {
  67.         if(gUartRxSta & 0x8000) {
  68.             //receive data length
  69.             len = gUartRxSta & 0x3fff;
  70.             if(len==0x1a && gUartRxBuf[0]=='T' && gUartRxBuf[1]==':') {
  71.                 sscanf(gUartRxBuf, "T:%04d-%02d-%02d %02d:%02d:%02d %2X", &year, &month, &day, &hour, &minute, &second, &crc);
  72.                 sprintf(buf, "%04d-%02d-%02d %02d:%02d:%02d\r\n", year, month, day, hour, minute, second);
  73.                 UART1_SendString(buf);
  74.                 LCD_DisplayNumber2(0, ((month/10)%10)?('0'+((month/10)%10)):' ', 0);
  75.                 LCD_DisplayNumber2(1, '0'+((month/1)%10), 0);
  76.                 LCD_DisplayNumber2(2, ((day/10)%10)?('0'+((day/10)%10)):'-', 0);
  77.                 LCD_DisplayNumber2(3, '0'+((day/1)%10), 0);
  78.                
  79.                 LCD_DisplayNumber1(0, ((hour/10)%10)?('0'+((hour/10)%10)):' ', 0);
  80.                 LCD_DisplayNumber1(1, '0'+((hour/1)%10), 0);
  81.                 LCD_DisplayNumber1(2, '0'+((minute/10)%10), 0);
  82.                 LCD_DisplayNumber1(3, '0'+((minute/1)%10), 0);
  83.                 LCD_DisplayNumber1(4, '0'+((second/10)%10), 0);
  84.                 LCD_DisplayNumber1(5, '0'+((second/1)%10), 0);
  85.                
  86.                 LCD_DisplayUnit(8,1);
  87.                 LCD_DisplayUnit(9,1);
  88.                
  89.                 LED1_OFF();
  90.                 LED2_OFF();
  91.                 LED3_OFF();
  92.                 LED4_OFF();
  93.                 if(GET_BIT(second, 0)) {
  94.                     LED1_ON();
  95.                 }
  96.                 if(GET_BIT(second, 1)) {
  97.                     LED2_ON();
  98.                 }
  99.                 if(GET_BIT(second, 2)) {
  100.                     LED3_ON();
  101.                 }
  102.                 if(GET_BIT(second, 3)) {
  103.                     LED4_ON();
  104.                 }
  105.             } else {
  106.                 DMA_NVIC_Send_Config(DMA1_Channel2, (u32)&UART1->TDR, (u32)gUartRxBuf, len);
  107.             }
  108.             gUartRxSta = 0;
  109.         }
  110.         else {
  111.             times++;
  112.             if(times % 5000 == 0) {
  113.                 UART1_SendString(APP_TITLE);
  114.             }

  115.             if(times % 500 == 0) UART1_SendString("I:Please input Data, End with Enter\r\n");
  116.             if(times % 50 == 0){
  117.                 LED1_TOGGLE();
  118.                 LED2_TOGGLE();
  119.                 LED3_TOGGLE();
  120.                 LED4_TOGGLE();
  121.             }
  122.             DELAY_Ms(100);
  123.         }
  124.     }

  125. }

  126. /// @}

  127. /// @}

  128. /// @}


其中的逻辑也不复杂,具体如下:
  • 初始化LED、SLCD、串口以及中断和DMA设置
  • LCD清屏,然后显示”2022 - ClocL“,没有K,只好用大L代替了
  • 然后就是检测接收状态了,收到了,且符合时间字符串的格式,则解析其中的年月日时分秒,然后显示到SLCD,并根据秒来确定对应的LED显示,实际上就是对应1、2、4、8

另外,还有下面两个地方的代码,需要修改:
11740638eb1a5b09d5.png

32659638eb1b35fe13.png
修改其中LED对应引脚的配置,以对应MM32L0136C7P开发板。

五、实际效果
将以上MM32L0136C7P开发板的代码,使用Keil编译下载后,就可以看到具体效果了:
【以下播放,加快了速度】
互联网时钟.gif


六、代码分享
1. 官方演示代码: MM32L0130_LibSamples_V020_1201.zip (5.49 MB, 下载次数: 5)
2. 本应用代码:https://gitee.com/honestqiao/MM32_SLCD_NTP_Net_CLock

要使用本应用的代码,请先下载官方演示代码,并解压,然后将 MM32_SLCD_NTP_Net_CLock 目录放置到 MM32L0130_LibSamples_V020/MM32L0130_Samples/SLCD下,具体如下: 77577638ebb43c3522.png
红色框柱的为关键代码,如果编译的时候提示找不到对应的文件,请自己添加一下到工程中。
  

10299823 发表于 2022-12-12 09:58 | 显示全部楼层
可以实现GPS的授时吗?              
dspmana 发表于 2022-12-12 12:02 | 显示全部楼层
这个不错,比较实用一些,NTP对时是趋势。
 楼主| HonestQiao 发表于 2023-1-7 14:30 | 显示全部楼层
10299823 发表于 2022-12-12 09:58
可以实现GPS的授时吗?

挂gps模块也可以呀
wwppd 发表于 2023-1-9 14:39 | 显示全部楼层
ntp是网络反馈时间吗?              
mikewalpole 发表于 2023-1-9 15:53 | 显示全部楼层
这个怎么解析的时间呢?              
1988020566 发表于 2023-1-11 20:48 | 显示全部楼层
怎么utc时间转换为北京时间?              
jackcat 发表于 2023-2-2 10:03 | 显示全部楼层
这个可以通过gps授时吧。              
ccook11 发表于 2023-2-2 12:01 | 显示全部楼层
NTP是网络数据的吗?              
alvpeg 发表于 2023-2-4 12:34 | 显示全部楼层
http访问方式。              
您需要登录后才可以回帖 登录 | 注册

本版积分规则

42

主题

115

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部