基于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.mzph.cn/news/812331.shtml

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

相关文章

解决mac本git安装后找不到命令的问题

不熟悉mac配置,折腾了半天,记录一下。 1.问题描述2.解决方法 1.问题描述 从https://sourceforge.net/projects/git-osx-installer/files/下载的git安装包: 安装时提示: 这里的解决办法是按住control键再打开文件安装。 安装完…

react antd 实现修改密码(原密码,新密码,再次输入新密码,新密码增加正则复杂度校验)

先看样子 组件代码: import React, { useState, useEffect } from react import { Row, Col, Modal, Spin, Input, Button, message, Form } from antd import { LockOutlined, EyeTwoTone, EyeInvisibleOutlined } from ant-design/icons import * as Serve from …

pyside6的QSpinBox自定义特性初步研究(二)

当前的需求是,蓝色背景的画面,需要一个相对应色系的QSpinBox部件。已有的部件风格是这样的,需要新的部件与之般配。 首先新建一个QDoubleSpinBox,并定义其背景色和边框: QDoubleSpinBox { color: white; border:1px…

基于无线物联网的智能配电监控系统设计应用

摘要:阐述基于电力物联网的智能配电监控系统的特点,探讨物联网结构及其关键技术,电力物联网下的智能配电监控系统设计,包括整体结构设计、硬件和软件系统设计。 安科瑞薛瑶瑶18701709087 关键词:电力物联网&#xff…

【好用】推荐10套后端管理系统前端模板

后台管理系统前端模板是开发者在构建后台管理系统时使用的一种工具,它提供了预先设计好的界面和组件,以帮助开发者快速搭建出功能完善、用户体验良好的管理系统。以下是V哥整理的10款流行的后台管理系统前端模板,它们基于不同的技术栈和设计理…

zookeeper分布式应用程序协调服务

一、zookeeper基本介绍 1.1 zookeeper的概念 Zookeeper是一个开源的分布式的,为分布式框架提供协调服务的Apache项目。 是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、…

[Python图像识别] 五十二.水书图像识别 (2)基于机器学习的濒危水书古文字识别研究

该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门、OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子、图像增强技术、图像分割等,后期结合深度学习研究图像识别、图像分类应用。目前我进入第二阶段Python图像识别,该部分主要以目标检测、图像…

CVPR 2024 | Retrieval-Augmented Open-Vocabulary Object Detection

CVPR 2024 - Retrieval-Augmented Open-Vocabulary Object Detection 论文:https://arxiv.org/abs/2404.05687代码:https://github.com/mlvlab/RALF原始文档:https://github.com/lartpang/blog/issues/13 本文提出了一种新的开放词汇目标检…

去除pycharm运行pytest的默认参数--no-header --no-summary -q

进入pycharm设置(Settings),找到高级设置(Advanced Settings)—>Python–>Pytest:不添加"–no-header --no-summary -q"(Pytest:do not add “–no-header --no-summary -q”)

2024年妈妈杯数学建模C题思路分析-物流网络分拣中心货量预测及人员排班

# 1 赛题 C 题 物流网络分拣中心货量预测及人员排班 电商物流网络在订单履约中由多个环节组成,图 ’ 是一个简化的物流 网络示意图。其中,分拣中心作为网络的中间环节,需要将包裹按照不同 流向进行分拣并发往下一个场地,最终使包裹…

Android中基于DWARF的stack unwind实现原理

一、简介 在软件开发中,unwind stack(栈回溯 或 调用栈展开)是调试和异常处理中至关重要的一环,通过理解其实现原理,可以更好地理解程序的执行流程,更有效地进行调试和错误排查。 本文主要介绍 AArch64 架构下的两种最典型的栈回溯…

RabbitMQ的介绍

为什么使用 MQ? 流量削峰和缓冲 如果订单系统最多能处理一万次订单,这个处理能力在足够应付正常时段的下单,但是在高峰期,可能会有两万次下单操作,订单系统只能处理一万次下单操作,剩下的一万次被阻塞。我们…

.NET JWT入坑

前言 JWT (JSON Web Token) 是一种安全传输信息的开放标准,由Header、Payload和Signature三部分组成。它主要用于身份验证、信息交换和授权。JWT可验证用户身份,确保访问权限,实现单点登录,并在客户端和服务器之间安全地交换信息…

SQLite 在Android安装与定制方案(十七)

返回:SQLite—系列文章目录 上一篇:SQLite超详细的编译时选项(十六) 下一篇:SQLite Android 绑定(十八) 安装 有三种方法可以将 SQLite Android 绑定添加到应用程序: 1、通过…

C++的stack和queue类(三):适配所有容器的反向迭代器

目录 前言 list的反向迭代器 list.h文件 ReverseIterator.h文件 test.cpp文件 前言 迭代器按性质分类: 单向:forward_list双向:list随机:vector / deque 迭代器按功能分类: 正向反向const list的反向迭代器…

深入理解Apache ZooKeeper与Kafka的协同工作原理

目录 引言 一、ZooKeeper基础概念 (一)ZooKeeper简介 (二)ZooKeeper数据结构 (三)ZooKeeper特点 (四)应用场景 二、ZooKeeper工作模式 (一)工作机制 …

请求分发场景下的鉴权问题

说明:记录一次对请求分发,无法登录系统的问题。 场景 如下,在此结构下,如何判断该用户是已登录的用户; 常规操作,用户登录后给用户发Token,同时将发放的Token存入到Redis中。要求用户后续请求…

架构设计-订单系统之订单系统的架构进化

1、单数据库架构 产品初期,技术团队的核心目标是:“快速实现产品需求,尽早对外提供服务”。 彼时的专车服务都连同一个 SQLServer 数据库,服务层已经按照业务领域做了一定程度的拆分。 这种架构非常简单,团队可以分开…

单片机方案 发声毛绒小黄鸭

随着科技的不断进步,智能早教已经成为了新时代儿童教育的趋势。智能早教玩具,一款集互动陪伴、启蒙教育、情感培养于一身的高科技产品。它不仅能陪伴孩子成长,还能在游戏中启迪智慧,是家长和孩子的理想选择。 酷得电子方案开发特…

股票价格预测 | Python使用GRU预测股票价格

文章目录 效果一览文章概述代码设计效果一览 文章概述 Python使用GRU预测股票价格 代码设计 import pandas as pd import matplotlib.pyplot as plt import numpy as np import tensorflow as tf from numpy