当前位置:   article > 正文

STM32同步NTP服务器时间_stm32 ntp

stm32 ntp

目录

一、NTP

 二、报文解析

三、代码


获取时间的方式有很多:GPS授时无卡CDMA授时网络授时等,NTP是通过Internet或局域网,从NTP服务器获取时间。

NTP时间服务器是用于局域网服务器时间同步使用的,可以保证局域网所有的服务器与时间服务器的时间保持一致,SP-SS06NTP授时服务器具有抗干扰性强、低功耗、多平台多系统支持、故障报警等功能,为网络设备(用户)提供精确、标准、安全、可靠和多功能的同步时间服务。

 那单片机想要连接NTP服务器,就需要接入网络,接入网络可以参考:

STM32驱动CH9121网络串口透传

或者说比较热门的ESP8266,ESP32这些无线接入的方式

一、NTP

详细的NTP协议移步更专业的文章:NTP服务器授时原理

客户端首先向服务端发送一个NTP 包,其中包含了该包离开客户端的时间戳T1,当服务端接收到该包时,依次填入包到达的时间戳T2、包离开的时间戳T3,然后立即把包返回给客户端。客户端在接收到响应包时,记录包返回的时间戳T4。

 二、报文解析

如果只是获取一个简单的时间,大可不必发送复杂的报文,Client发送的报文只需要这样:

总共48个字节,23表示是Client,也可以是1b

NTP服务器返回的数据:

 

 

简单点,第41到48个字节取出来,转换成十进制数就是一个时间戳,这是相对于1970年的时间戳。

三、代码

1.发送请求报文,这个根据连接方式不同,代码不同,不做笔记

2.接收报文分析:

一些定义:

  1. #define SEC_1900_1970 (2208988800UL) //(1900-1970年的秒数)
  2. typedef struct
  3. {
  4. int year;
  5. uint8_t month;
  6. uint8_t day;
  7. uint8_t hour;
  8. uint8_t minute;
  9. uint8_t second;
  10. }Time;
  1. //从NTP报文中获取时间,返回0表示获取成功,时间正确性高,返回1表示获取失败
  2. //@data: 报文指针,48个字节
  3. //@time:用于存放时间的Time指针变量
  4. uint8_t NTP_GetTime(uint8_t *data , Time *t)
  5. {
  6. int time_stamp;
  7. struct tm *tm;
  8. time_t tick;
  9. time_stamp = (data[40]<<24)|(data[41]<<16)|(data[42]<<8)|(data[43]<<0); //相对于1970
  10. time_stamp -= SEC_1900_1970; //得到相对于1900的时间戳
  11. tick = (time_t)time_stamp;
  12. tm = localtime(&tick);
  13. t->year = tm->tm_year+1900;
  14. t->month = tm->tm_mon+1;
  15. t->day = tm->tm_mday;
  16. t->hour = tm->tm_hour;
  17. t->minute = tm->tm_min;
  18. t->second = tm->tm_sec;
  19. UTCToBeijing(t); //UTC时间转为北京时间
  20. if((t->year>0)&&(t->month>0)&&(t->month<13)&&(t->day>0)&&(t->day<32)&&(t->hour>0)&&(t->hour<24)&&(t->minute<60)&&(t->second<60)) //判断范围是否正确
  21. {
  22. return 1;
  23. }else
  24. {
  25. return 0;
  26. }
  27. }
  28. void UTCToBeijing(Time *UTC)
  29. {
  30. int year=0,month=0,day=0,hour=0;
  31. int lastday = 0;// 月的最后一天日期
  32. year=UTC->year;
  33. month=UTC->month;
  34. day=UTC->day;
  35. hour=UTC->hour+8;//UTC+8转换为北京时间
  36. if(month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12)
  37. {
  38. lastday = 31;
  39. }
  40. else if(month == 4 || month == 6 || month == 9 || month == 11)
  41. {
  42. lastday = 30;
  43. }
  44. else
  45. {
  46. if((year%400 == 0)||(year%4 == 0 && year%100 != 0))//闰年的2月为29天,平年为28天
  47. lastday = 29;
  48. else
  49. lastday = 28;
  50. }
  51. if(hour >= 24)//当算出的时大于或等于24:00时,应减去24:00,日期加一天
  52. {
  53. hour -= 24;
  54. day += 1;
  55. if(day > lastday)//当算出的日期大于该月最后一天时,应减去该月最后一天的日期,月份加上一个月
  56. {
  57. day -= lastday;
  58. month += 1;
  59. if(month > 12)//当算出的月份大于12,应减去12,年份加上1年
  60. {
  61. month -= 12;
  62. year += 1;
  63. }
  64. }
  65. }
  66. UTC->year = year;
  67. UTC->month = month;
  68. UTC->day = day;
  69. UTC->hour = hour;
  70. }

NTP的时间戳是相对于1970年,而localtime函数是相对于1900年的时间戳转换,所以NTP的时间戳要减去1970-1900的秒数,转换出来之后是UTC时间,再转换为北京时间。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/553508
推荐阅读
相关标签
  

闽ICP备14008679号