基于STM32G031LORA开发板的时间同步项目

一、前言

        本项目采用淘宝购买的STM32G031开发板,板上预留了oled和LORA模块的IO,一次性买了四套,资料虽然质量不高,但是覆盖面挺广,有一定的学习价值。

        实验目的是需要三个从机实现时间轴的一致,考虑到现有环境下的各种干扰,希望做到1ms以内的误差。采用一个主机来完成对所有从机的时间校对,减小上位机的任务,同时也更符合后期调试的需要。

二、实现细节

1、定时器配置

        每个单片机的时间轴采用定时器计数的方式,来作为本地的时间轴。因为需要尽可能的提高精度,所以采用了频率最高的TIM1做基准时钟(128MHz),采用计数周期最大的TIM2做计数时钟(32bit)。采用定时器级联的方式,也就是手册中的TIM1作为TIM2的预分频,最高可以实现约610.839小时的计数。

        主从模式的配置需要注意几个点:

首先是TIM1:

        作为基准时钟,正常配置为周期计数即可,如果需要PWM或者别的功能,每个通道也都可以正常使用。

        然后是计数配置,这里设置向上计数,装载值64000,不分频,开启自动装载,其余部分默认即可。

TRGO部分开启,第一个设置为更新时间触发,就是满一个周期,TIM2计数加1。

TRGO没有使用,随意。

然后是TIM2:

从模式选择外部时钟,Trigger Source的选择具体要查看数据手册,这里放一张截图:

在数据手册定时器寄存器讲解部分可以找到这个图,需要选择对应的通道,这里选择IRT0。

        计数配置如下:

TRGO部分用不到,关闭即可。

        本实验将两个定时器的满装载值定为64000和172,800,000,TIM1一个周期0.5ms,TIM2一个周期24小时。

2、LORA配置

        lora模块采用的是Ebyte的E22-400T22D,配置方面不做介绍,可以使用上位机配置,也可以根据官方的数据手册配置模块的寄存器。

        本实验采用的配置为:

主机地址为0xFFFF,实现广播和监听;

从机地址0x03~0x05;

网络地址0x17;

波特率115200,配置寄存器时只能使用9600;

透传模式;

空中速率19.2k;

频率信道60;

以上配置仅作参考,读者需要根据实际需要进行调整。

        注意M0和M1配置引脚的使用,lora芯片内部默认上拉,传输模式时两个引脚都需要接地。

实验采用单片机通过串口配置lora,所以贴出指令:

//主lora模块地址固定为0x01,其余保持默认值。C0+起始地址+长度+参数
//网络地址Cmd_Set_board[5]和信道控制Cmd_Set_board[8]可自行指定
const uint8_t Cmd_Set_master_board[12]={0xC0, 0x00, 0x09, 0xff, 0xff, 0x17, 0xe5, 0x00, 0x50, 0x00, 0x00, 0x00};

3、时间同步

        同步方式采用最简单的双向交互,具体流程如下:

(1)主机发送时间同步请求,并记录当前时间;

(2)从机收到后立即做出应答;

(3)主机收到应答,计算发送时间与当前时间的误差,将偏移后的时间发送至从机。

        发送时间的方式,是直接将两个定时器的计数值作为数据通过lora发送,通过一些固定位来作为标志位,来辨别是哪一帧数据,哪一个从机的数据,是否是有效数据。

        本实验方法较为简单,有很多可以优化的流程,另外时间偏移的计算也可以放到从机。

具体实现细节读者可以自行设计,本实验的方法最后会贴出代码作为参考,也希望各位读者给出修改意见,提高同步精度。

4、oled刷新

        由于之前的单片机项目,屏幕刷新几乎不会做太多文章。由于时间精度的需要,采用延时的方法已将无法达到要求。

        尝试过放在定时器溢出中断来做刷新,可是刷新还是比较耗时,影响定时器效率,于是采用标志位的方式,把oled刷新放到主函数,但是这样代码难免会有所冗余。

        最后是采用读取定时器计数值的方式,每隔50ms刷新一次,这样也能保持时间同步之后的刷新一致。

三、实验结果

        测试方式,根据本地时间轴每隔50ms开关一次引脚,测量所有开发板的引脚波形,最后实测能够达到主从1ms误差,从设备0.5ms左右。

四、最后

        实验将主从模块一起开发,通过main.h文件的开关切换主从代码。

        实验中有很多细节没有提到,描述也比较简单,应该是我太懒了哈哈哈哈,各个模块之间耦合比较多,没有办法拆开一个个细说,还请读者在源码中查看。

        代码根据CubeMX生成,添加了delay延时和uart驱动,可以作为STM32G031的例程模板来开发,代码风格是学习的正点原子,应该适合大家的阅读习惯。

更新:

        代码将TIM2部分换成了变量计数,好像精度提高了,还有细节部分的更改,以下是gitee链接:

stm32: 一些stm32模块使用经验记录 - Gitee.comicon-default.png?t=N7T8https://gitee.com/lrf1125962926/stm32/tree/Time_Sync/

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

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

相关文章

鸿蒙原生应用元服务开发-WebGL网页图形库开发接口说明

一、场景介绍 WebGL主要帮助开发者在前端开发中完成图形图像的相关处理,比如绘制彩色图形等。目前该功能仅支持使用兼容JS的类Web开发范式开发。 二、接口说明 表1 WebGL主要接口列表 本文参考引用HarmonyOS官方开发文档,基于API9。

期货开户市场的风险在哪里?

期货市场的风险在哪里?强平和穿仓是什么? 期货市场是一个自带杠杆的市场,简单理解就是我们只需要用10W就能买到价值100万的商品。期货主要的风险来源于仓位风险和交割风险,仓位风险就是我们是采用满仓还是轻仓方式交易。比如我们…

32个关键字详解①(C语言)

目录 关键字分类: 第一个C程序 - 补充内容 变量的定义与声明 - 补充内容 变量的分类 - 补充内容 变量的作用域 - 补充内容 变量的生命周期 - 补充内容 auto 关键字 register 关键字 static 关键字 static 修饰变量: static修饰函数 sizeof 关键字 基本数…

docker私有仓库-harbor的搭建

docker 官方提供的私有仓库 registry,用起来虽然简单 ,但在管理的功能上存在不足。 Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器,harbor使用的是官方的docker registry(v2命名是distribution)服务去完成。harbor在docker di…

全排列+力扣

题目 题目链接 . - 力扣&#xff08;LeetCode&#xff09; 题目描述 代码实现 class Solution {vector<vector<int>> ret;vector<int> path;bool used[7]; public:vector<vector<int>> permute(vector<int>& nums) {_permute(nums…

C++_包装器

目录 1、包装器的用法 2、包装器的类型 3、包装器的作用 4、包装成员函数 5、bind&#xff08;绑定&#xff09; 5.1 bind的用法 5.2 bind减少参数个数 结语 前言&#xff1a; C11的包装器&#xff0c;总称为function包装器&#xff0c;而包装器又称适配器…

allegro PCB设计心得笔记(二) -- ERROR(SPMHUT-144): Illegal arc specification

使用Allegro PCB Editor设计PCB&#xff0c;其中使用了中文丝印&#xff0c;设计完成后&#xff0c;进行Tools -> Database Check&#xff0c;提示如下错误&#xff1a; 对PCB文件进行反复检查&#xff0c;也没有找到具体问题&#xff0c;但是删除中文丝印封装后&#xff0c…

vue3 uniapp 项目初始化集成配置【开箱即用】

https://gitee.com/charrie/vue3-uniapp-init 技术说明 采用vue3viteuniapp技术栈&#xff0c;setup语法糖编码方式引入unocss量子化样式引擎&#xff0c;动态css不用自己写样式&#xff0c;引用class即可&#xff0c;降低代码体积全局请求入口已封装&#xff0c;使用时自己封…

宝塔面板配置网站通过ip地址+端口,页面刷新无效。nginx反向代理后端端口。添加/xxx文件然后再访问项目。

宝塔面板配置网站通过ip地址端口&#xff0c;页面刷新无效。nginx反向代理后端端口。添加/xxx文件然后再访问项目。 一般来说vue项目build打包以后 如果 直接发布服务器 并且不使用后端接口。 是不需要配置nginx的。 假设我vue部署好了。我的ip是106.66.66.66. 但是我页面里面…

PLC数据采集网关是如何应用的?-天拓四方

PLC数据采集网关通过以太网、串口等通信接口与PLC设备连接&#xff0c;实现数据的实时采集。网关内置数据处理模块&#xff0c;可以对采集到的数据进行清洗、转换和存储&#xff0c;以满足不同应用场景的需求。同时&#xff0c;PLC数据采集网关支持多种通信协议&#xff0c;如M…

1.Spring核心功能梳理

概述 本篇旨在整体的梳理一下Spring的核心功能,让我们对Spring的整体印象更加具体深刻,为接下来的Spring学习打下基础。 本片主体内容如下: Bean的生命周期依赖注入的实现Bean初始化原理推断构造方法原理AOP的实现这里要说明一下,我们这里说到的Spring,一般指的是Spring F…

基于Java (spring-boot)的房屋租赁系统

一、项目介绍 有以下模块 角色&#xff1a;用户、管理员、房东 管理员&#xff1a;个人中心、房屋类型管理、房屋信息管理、预约看房管理、合同信息管理、房屋报修管理、房屋评价管理、系统管理 用户:个人中心、房屋信息管理、预约看房管理、合同信息管理、房屋报修管理、房屋…

差分逻辑电平 --- LVDS、CML、LVPECL互连

前言 首先了解差分逻辑电平结构&#xff0c;也包括单端逻辑电平 地址&#xff1a;常见的逻辑电平_常用的逻辑电平-CSDN博客 注&#xff1a;ECL >> PECL >> LVPECL演变而来&#xff1b;QDR&#xff08;Quad Data Rate):四倍数据倍率 本文章只涉及差分逻辑电平:LVDS…

在dpvs上实现ICMP的源进源出

目录 1. 缘起2. 源码分析3. 让ICMP也走源进源出1. 缘起 在网络通信中,当一个请求报文从源主机到达目标主机,并经过中间路由器或交换机进行转发时,请求报文进入主机A的路径和响应报文离开主机A的路径可能不同。这种情况下,就会出现所谓的三角路径问题。如下图: 具体来说,…

C++第二弹---C++入门(中)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】 C入门 1、函数重载 1.1、函数重载概念 1.2、C支持函数重载的原理--名字修饰(name Mangling) 3、引用 3.1、引用概念 3.2、引用特性 3.3、常引用 …

批量PDF转HTML:高效管理与优化文档格式

随着数字化时代的快速发展&#xff0c;PDF文件因其跨平台兼容性和良好的排版效果而被广泛应用。然而&#xff0c;在文本批量管理的场景中&#xff0c;我们可能需要将PDF文件转换为HTML格式&#xff0c;以便更好地进行编辑、搜索和定制。本文将为您介绍一种高效的方法&#xff0…

Java线程的基本操作

线程的基本操作 Java线程的常用操作都定义在Thread类中&#xff0c;包括一些重要的静态方法 和线程的实例方法 。下面我们来学习一下&#xff0c;线程的常用基本操作 1.线程名称的设置和获取 线程名称可以通过构造Thread的时候进行设置&#xff0c;也可以通过实例的方法setName…

NOIP2018-S-DAY1-3-赛道修建(洛谷P5021)的题解

目录 题目 原题描述&#xff1a; 题目描述 输入格式 输出格式 输入输出样例 主要思路&#xff1a; check&#xff1a; 真正的code: 原题描述&#xff1a; 题目描述 C 城将要举办一系列的赛车比赛。在比赛前&#xff0c;需要在城内修建 条赛道。 C 城一共有 个路…

rancher里的ingress如何配置gzip压缩

方案一&#xff0c;未试验成功&#xff0c;但配置过程值得记录一下 通过配置configmap&#xff0c;然后在ingress的deployment里引用configmap实现。 参考文章 创建configmap apiVersion: v1 kind: ConfigMap metadata:name: nginx-ingress-controllerannotations:{} # k…

WPF Button去除按钮边框,添加下划线

<Button Width"45" Height"25" FontSize"20" Background"Transparent" BorderBrush"Transparent" Foreground"#FFC9A322" Click"Btn_Retry_Click" ><TextBlock><Underline>重试</…