基于STM32F103单片机的时间同步项目

一、前言

        本项目为前一个时间同步项目的更迭版本,由于之前的G031开发板没有外部晶振,从机守时能力几乎没有,5秒以上不同步从机时间就开始飞了。在考虑成本选型后,选择了带有外部有缘晶振的STM32F103C8T6最小单片机,来作为本次项目的开发平台。

        G031时间同步链接:

基于STM32G031LORA开发板的时间同步项目-CSDN博客https://blog.csdn.net/plmm__/article/details/136646460?spm=1001.2014.3001.5501        之前的物联网模块采用EByte的LORA模块,由于是串口控制与数据发送,波特率最高115200,对于发送数据有时间延迟,虽然在双向校时中可以计算在内,但除去一个干扰因素总是好的。

        新的设备改用2.4G模块,接口为SPI,通信速率最大10M,能提高效率,再加上模块的地址扩展性,从机设备的数量可以大大提升。

        

二、主体框架

       1、使用设备

        本项目采用一主六从的实验环境,用逻辑分析仪抓取心跳灯的闪烁时间戳,从而获取每个设备间的相对时间间隔:

460d15e2e49b422d8819a41d86149800.jpeg

        2、代码结构

        相较于前一份工程,我尽可能的根据自己的理解,将驱动层和应用层分离,减少代码的耦合性,提高移植能力和复用性,尽可能作为一个模板工程,可以后续开发其他项目。

100d8e22987e4fd1b174dd53147f1140.png

        所有与硬件无关的应用层代码都由Time_SYNC.c文件调用与实现,主要是时间同步的主体逻辑与各个外设间的联动,具体代码可看gitee仓库。

        其他驱动文件对应的调用函数,例如定时器中断溢出,外部中断,串口中断等,我通过宏定义的形式,在驱动对应的头文件中提供用户接口,将函数实现主体抽象到应用层函数中来:

        TIM.h头文件:ca3c9beb9d8c484682883c93a298e80d.png

        TIM.c驱动:

536579a4e4cd4b72a3d1b8719bd5624d.png

        Time_SYNC.c文件的实现:

fcd0afd122f144dd9f6222cc214e4e1a.png

        宏定义是c的一大杀器,我本人很喜欢用,能显著提高代码的可阅读性,同时又不更改代码的执行逻辑。

       3、时间同步原理

       1.时基

        每个设备都有一个时基定时器,精度为1us,也就是定时器每加1,时间加1us。

        装载值设为1000,溢出中断为1ms计时,在溢出中断中将变量Time_Base加一,因此一个设备的本地时间轴就由两部分组成,小时间定时器计数值,单位us;大时间Time_Base变量,单位ms。所以在数据包中,就要同时读取和发送两个值。

        与前一个项目的定时器级联不同,本次采用变量来作为第二级时间,一是方便调试,可以轻松查看变量的值,二是提高时间读取速度,比读定时器的寄存器应该要更快。

        __IO就是volatile关键字,由HAL库封装。

        8b7a56f254504a008cc718cb1f22e77a.png

066456833b034cbf8e5e838feda4d5a6.png

        

        2.主机轮询请求

        主机通过100ms定时器,也即是上一节图中TIM3,超时则向一个从机发起同步请求,调用函数Single_Send_TIM_Callback,对从机号进行处理和保存,从机的同步为顺序逐个进行。从机号的处理放到请求开始前,是为了保持任意从机掉线,主机也能继续处理下一个从机。

        设置本次从机号后,调用发送函数:

85c264291d0049dface4088b9bdb8857.png

        数据包内容如上图,带有两个时间和从机号,以及标志位。

        

        3.从机接收做出应答

        从机接收到数据后会做对时间数据进行保留,并立即做出回应,回应内容为自定格式,只需要确保从机号和标志位正确:

94ecf67a850447b0ad27ef6036c3e049.png

0a17bc7230d94c789ed9a1ebe1a61cae.png

        

        4.主机接收应答发送第二次时间

        主机收到从机应答后,再次获取本地时间,立即发送至从机:9a290f671c9642a3a7fb2a52235d2542.png

 

        5.从机接收到第二次时间   c3a15182f2c641499a8e9b0b48f0fe16.png

        至此,一次交互结束。

        此时从机有两个主机发送的时间,两个时间的差值,便是主机第一次发送,到收到从机应答的时间,除2后便是单向传输耗时。这个过程需要尽量保持主机发送和从机发送的时间相同,因此传输的数据长度要保持一致。

        对时间的差值我放到了最后集中处理。

       

        6.计算均值

        对于同一个从机,将同步过程连续进行10次,若从机收到有效数据大于6个,则进入数据计算函数:

        9a51b82622584fb28a118ca8d4addfd1.png

        这里的关中断原本是关闭所有,时基定时器也关闭,但是因为计算过程中如果有不规范数据,会放弃本次同步,所以本地时间轴就会偏移本次的计算时长。为了防止此问题,最后只关闭了外部中断。

        Slave_Data_Process函数是时间同步的关键步骤,这部分是由从机自身来计算,主机不去干扰。上一个项目是主机对每个从机的时间偏移计算后下发至从机,会拖慢主机的执行效率。c0da631e04a94a9dbf5897996486a2ec.png

        这部分代码较长,主要作用就是将10次得到的数据做差值,并对边界问题做处理,最后将所有计算耗时记录下来,在得出时间差后补偿到最后的时间中。

        将最后一次收到的时间作为修正基准:

e32317a69dad45b18689a11b7f6a06ca.png

        补偿至最后的时间中,最后更新本地时间:b2301608069d4a78b6f91ff0f0d3c1f6.png

        

三、实验结果

220a019a93164b4994207ccfbbb58644.png

        第一行为主机时间轴,最大误差出现在黄色,39.8us。

        经过多次同步,所有从机的时间误差的前后关系几乎保持与上图一致,也就是黄色一直都是最大,其他也都是保持这个位置。

        由于从机代码的一致性,也更换过2.4G模块,这个问题大概率是单片机硬件导致,目前暂时不做深究。

四、总结

        该时间同步项目有很多应用场景,可以单独作为一个时间同步器应用到实际场景中。

        由于在新框架中加入了很多优化,对之前的冗余操作和时间同步方案做了大规模优化,所以工程的流程更加复杂。从代码来看,新旧版本已经没有太多关联性,可以说是两个独立的项目了。

        有关代码的实现细节有很多都没有具体展开讲,本片博客主要在于分享框架,读者可以自行阅读代码,如有不清楚的地方可以私信我;同时也欢迎各位读者对本项目提出优化意见,我将更新后推送至仓库。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/307030.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DRF的认证、权限、限流、序列化、反序列化

DRF的认证、权限、限流、序列化、反序列化 一、认证1、直接用,用户授权2、认证组件源码3、第三方认证djangorestframework-simplejwt 二、权限1. 直接使用,用户权限2.权限组件源码 三、序列化1. 序列化1.1 自定义Serailizer类序列化1.2 在视图APIView中使…

嵌入式驱动学习第七周——GPIO子系统

前言 GPIO子系统是用来统一便捷地访问实现输入输出中断等效果。 嵌入式驱动学习专栏将详细记录博主学习驱动的详细过程,未来预计四个月将高强度更新本专栏,喜欢的可以关注本博主并订阅本专栏,一起讨论一起学习。现在关注就是老粉啦&#xff0…

spring boot整合Redis监听数据变化

一、前言 Redis提供了数据变化的通知事件,可以实时监测key和value的变化,客户端可以通过订阅相关的channel来接收这些通知事件,然后做相应的自定义处理,详细的介绍可以参考官方文档Redis keyspace notifications | Docs 使用Red…

httpsok-快速申请谷歌SSL免费证书

🔥httpsok-快速申请谷歌SSL免费证书 使用场景: 部署CDN证书、OSS云存储证书证书类型: 单域名 多域名 通配符域名 混合域名证书厂商: ZeroSSL Lets Encrypt Google证书加密类型: ECC、 RSA 一、证书管理 进入 证书管…

【数学建模】2024Mathorcup数学建模C题完整思路与代码论文解析

2024Mathorcup数学应用挑战赛C题|图神经网络的预测模型ARIMA时间序列预测模型人员排班混合整数规划模型|完整代码和论文全解全析 我们已经完成了2024Mathorcup数学建模挑战赛C题的40页完整论文和代码,相关内容可见文末,部分图片如下: 问题分…

[蓝桥杯] 岛屿个数(C语言)

提示: 橙色字体为需要注意部分,红色字体为难点部分,会在文章“重难点解答”部分精讲。 题目链接 蓝桥杯2023年第十四届省赛真题-岛屿个数 - C语言网 题目理解 这道题让我们求岛屿个数,那么我们就应该先弄懂,对于一…

Qt5 编译oracle数据库

库文件 1、Qt源码目录:D:\Qt5\5.15.2\Src\qtbase\src\plugins\sqldrivers\oci 2、oracle客户端SDK: https://www.oracle.com/database/technologies/instant-client/winx64-64-downloads.html 下载各版本中的如下压缩包,一定要版本相同的 将两个压缩包…

【简单讲解如何安装与配置Composer】

🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出…

Rust语言入门第四篇-变量与可变性以及隐藏(Shadowing)

文章目录 Rust语言入门第四篇-变量与可变性以及隐藏(Shadowing)概要let 关键字自动判断变量类型隐藏(Shadowing)let关键字支持的数据类型let 关键字声明的变量类型转换 Rust语言入门第四篇-变量与可变性以及隐藏(Shado…

机器学习和深度学习 -- 李宏毅(笔记与个人理解)Day 13

Day13 Error surface is rugged…… Tips for training :Adaptive Learning Rate critical point is not the difficult Root mean Square --used in Adagrad 这里为啥是前面的g的和而不是直接只除以当前呢? 这种方法的目的是防止学习率在训练过程中快速衰减。如果只用当前的…

02_JavaWeb中的Tomcat(详解)

文章目录 Tomcat1, 概述1.1 安装1.2 目录结构1.3 启动/停止 2, 资源部署2.1 直接部署: 主要和重要的方式2.2 虚拟映射: 重要2.2.1 方式一:2.2.1 方式二: 2.3 原理解析 3, Tomcat组件3.1 Connector3.2 Engine3.2.1 Host3.2.1.1 Context 4, 其它: 重要4.1 设置 Tomcat 1, 概述 w…

Android网络抓包--Charles

一、Android抓包方式 对Https降级进行抓包,降级成Http使用抓包工具对Https进行抓包 二、常用的抓包工具 wireshark:侧重于TCP、UDP传输层,HTTP/HTTPS也能抓包,但不能解密HTTPS报文。比较复杂fiddler:支持HTTP/HTTPS…

文献速递:深度学习肝脏肿瘤诊断---基于多相增强 CT 和临床数据的恶性肝肿瘤鉴别诊断深度学习

Title 题目 Deep learning for diferential diagnosisof malignant hepatic tumors based on multi-phase contrast-enhanced CT and clinical data 基于多相增强 CT 和临床数据的恶性肝肿瘤鉴别诊断深度学习 Abstract 摘要 Liver cancer remains the leading cause of can…

云计算:Linux 部署 OVS 集群(控制端)实现OpenFlow

目录 一、实验 1.环境 2.Linux 部署 OVS 集群(控制端) 3.控制端对接服务端OVS网元 4.服务端OVS添加流表 5.服务端删除OVS 二、问题 1. ODL如何查找已安装插件 2.查看流表显示不全 3.如何删除OVS流表 一、实验 1.环境 (1) 主机 表1 宿主机 主…

什么是NLP?

🤖NLP是什么?🤖 NLP(Natural Language Processing),全称自然语言处理,是人工智能不可或缺的一环,它搭建了人与计算机之间沟通的桥梁🌉。 🛠️NLP强大功能一…

【自然语言】使用词袋模型,TF-IDF模型和Word2Vec模型进行文本向量化

一、任务目标 python代码写将 HarryPorter 电子书作为语料库,分别使用词袋模型,TF-IDF模型和Word2Vec模型进行文本向量化。 1. 首先将数据预处理,Word2Vec 训练时要求考虑每个单词前后的五个词汇,地址为 作为其上下文 &#xf…

CTFshow电子取证——内存取证1

关于内存与注册表 内存中的注册表项 当Windows操作系统启动时,它会将注册表的部分数据加载到内存中,以便系统和应用程序可以快速地访问这些信息。这些数据在内存中可以更快地被读取和修改,以便系统能够动态地调整其行为和配置。 系统性能和…

Ubuntu (Linux系统) 下载安装 Qt 环境

在官网http://download.qt.io/archive/qt/ 下载安装包,默认linux平台下提供的安装包以run后缀结尾 也可以选择其它地址下载 Qt官网下载地址:https://download.qt.io; 国内镜像下载地址:https://mirrors.cloud.tencent.com/qt/ 。建…

稀碎从零算法笔记Day47-LeetCode:找到冠军 I

或许是昨天的每日一题太难了,今天的简单 题型:数组、矩阵 链接:2923. 找到冠军 I - 力扣(LeetCode) 来源:LeetCode 题目描述 一场比赛中共有 n 支队伍,按从 0 到 n - 1 编号。 给你一个下…

在vue3中实现pptx、word、excel预览

插件推荐 PPTXjs vue-office 代码 <script setup lang"ts" name"home"> import { computed, nextTick, ref, onMounted } from vue; //引入VueOfficeDocx组件 import VueOfficeDocx from vue-office/docx; //引入VueOfficeExcel组件 import VueOf…