当前位置: 首页 > news >正文

细说STM32单片机USART中断收发RTC实时时间并改善其鲁棒性的方法

目录

一、工程目的

1、 目标

2、通讯协议及应对错误指令的处理目标

二、工程设置

三、程序改进

四、下载与调试

1、合规的指令 

2、 proBuffer[0]不是#

3、proBuffer[4]不是;

4、指令长度小于5

5、指令长度大于5

6、proBuffer[2]或proBuffer[3]不是数字

7、';'位于proBuffer[2]或proBuffer[3]位置 


        在本文作者的文章(参考文章):细说STM32单片机USART中断实现收发控制的方法_stm32 uart 中断接收-CSDN博客  https://wenchm.blog.csdn.net/article/details/143189217 中作者曾经建立了一个Cube IDE工程,利用STM32单片机的USART2串口中断程序,实现单片机接收由串口助手发送来的指令,根据指令更新RTC时间,再通过USART2串口向串口助手发送RTC时间。

        参考文章的缺点是,程序简单,没有考虑到干扰指令的影响。程序的鲁棒性很差,除了必须严格按照表格中的协议输入指令外,程序对于不知情、不甚了解协议得错误输入没有鉴别和应急处理的措施。

        本文中,作者对不同情况下输入的错误指令,在程序中提供了对应的应急处理方法和错误信息提示。提高了程序的鲁棒性和可用性。

一、工程目的

1、 目标

        除参考文章中提到的设计目的之外,重点解决程序设计的鲁棒性:对不同的指令输入的应急处理能力、消息提示。

2、通讯协议及应对错误指令的处理目标

        通讯协议(同参考文件)及不同情景下的对错误指令的应急处理方案,对照表如下:

上位机发送的指令字符串

指令功能

操作说明

#H13;

设置小时,将RTC时间的小时修改为13

#M32;

设置分钟,将RTC时间的分钟修改为32

#S05;

设置秒,将RTC时间的秒修改为5

#U01;

恢复上传时间数据

#U00;

停止上传时间数据

&H13;

proBuffer[0]不是#

#H13!

proBuffer[4]不是;

#HER;#H6R;#HE6;

proBuffer[2]或proBuffer[3]不是数字

#Y13;

proBuffer[1]不是H、M、S、U

#H9;

指令长度小于5

第一次输入,串口助手没有相应,因为,

串口接收中断没有接收到足够的5个

字节数据,没有产生中断。第二次输入,

助手显示#H9;#,执行相应的应急处理

程序,清空缓存,重启串口。

#H192;

指令长度大于5

第一次输入。串口助手显示#H192,因

为proBuffer[4]不是;执行相应的处理程序

#H19;2

指令长度大于5

第一次输入。串口助手显示#H19;程

序正常处理,下一中断,助手显示2****

,因为proBuffer[0]不是#,执行相应

的应急处理程序,清空缓存,重启串口。

#H30;

小时的数值范围不属于[0,24]

#M70;

分钟的数值范围不属于[0,60]

#S70;

秒的数值范围不属于[0,60]

二、工程设置

        与参考文章相同。

三、程序改进

        受影响的程序只有usart.c,且只需修改其中的函数void updateRTCTime()。

/*根据串口接受来的指令字符串,更新修改RTC时间*/
void updateRTCTime()
{unsigned char hello1[]="Invalid command\n";unsigned char hello2[]="Invalid data\n";/* -0x30 操作用于将ASCII码表示的字符(假设是数字'0'~'9')转换为其对应的整数 */uint8_t timeSection = proBuffer[1]; //类型字符uint8_t tmp10 = proBuffer[2]-0x30; 	//十位uint8_t tmp1 = proBuffer[3]-0x30; 	//个位uint8_t val= 10*tmp10+tmp1;//  Identify the start_bit is '#',the end_bit is ';'or not,
// Regardless of whether the input characters are less than 5 or more than 5, they will all be processed by this program in the end.
// No matter how you clear the buffer, the data received next time will not be complete.
// This situation will never improve until the serial port is restarted.if (rxBuffer[0] != '#' ||  rxBuffer[4] != ';'){HAL_UART_Transmit(&huart2,hello1,sizeof(hello1),200);memset(rxBuffer, '\0', sizeof(rxBuffer));memset(proBuffer, '\0', sizeof(proBuffer));HAL_UART_Init(&huart2);	//重启串口rxCompleted = RESET;HAL_UART_Receive_IT(&huart2, rxBuffer, RX_CMD_LEN);return;}// Identify the data_bit is digits or notif (isalpha(proBuffer[2])  || isalpha(proBuffer[3])){HAL_UART_Transmit(&huart2,hello2,sizeof(hello2),200);memset(proBuffer, '\0', sizeof(proBuffer));return;}//update RTCtimeRTC_TimeTypeDef sTime;RTC_DateTypeDef sDate;if (HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN) == HAL_OK){//调用HAL_RTC_GetTime()之后必须调用HAL_RTC_GetDate()以解锁数据,才能连续更新Date and TimeHAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);switch (timeSection){case 'H': // 修改小时{if(val <= 24)sTime.Hours = val;else{HAL_UART_Transmit(&huart2,hello2,sizeof(hello2),200);memset(proBuffer, '\0', sizeof(proBuffer));return;}}break;case 'M': // 修改分钟{if(val <= 60)sTime.Minutes = val;else{HAL_UART_Transmit(&huart2,hello2,sizeof(hello2),200);memset(proBuffer, '\0', sizeof(proBuffer));return;}}break;case 'S': // 修改秒{if(val <= 60)sTime.Seconds = val;else{HAL_UART_Transmit(&huart2,hello2,sizeof(hello2),200);memset(proBuffer, '\0', sizeof(proBuffer));return;}}break;case 'U':{if( tmp1 == 0){isUploadTime = 0;//pausereturn;}elseisUploadTime = 1; //resume}break;default: // 不是 'H', 'M' , 'S','U'则返回{HAL_UART_Transmit(&huart2,hello1,sizeof(hello1),200);memset(proBuffer, '\0', sizeof(proBuffer));}return;}HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN); //设置RTC时间影响到下一次唤醒}
}

四、下载与调试

         本文的重点在于调试。测试各种情况下新设计的程序的鲁棒性:对各种错误的输入的应急处理能力和信息提示。

1、合规的指令 

2、 proBuffer[0]不是#

         指令不符合格式,显示指令错误。

3、proBuffer[4]不是;

        指令不符合格式,显示指令错误。

4、指令长度小于5

         指令长度小于5时,第一次输入后,看不到相应,再次输入后,显示错误的指令字符(只显示前5个字节),执行应急处理程序,清除缓存,重置串口初始化。

        如果不重置串口初始化,无论怎么输入,程序接收到的数据总是陷入混乱的状态。

 

5、指令长度大于5

    指令长度小于5时,显示指令错误。当proBuffer[4]=;时,如果前面的数据符合格式,那么执行数据更新;再次 输入指令后,显示指令错误,并执行相应的应急处理程序,清空缓存,重置串口。

6、proBuffer[2]或proBuffer[3]不是数字

        显示数据错误。

7、';'位于proBuffer[2]或proBuffer[3]位置 

         显示指令错误。

         其它没有测试到的错误指令输入的情形,感兴趣的网友亲测吧。

        本方法,只限于大写字母,没有提供区分大小写字母的算法,感兴趣的网友可以自己去完善。

相关文章:

细说STM32单片机USART中断收发RTC实时时间并改善其鲁棒性的方法

目录 一、工程目的 1、 目标 2、通讯协议及应对错误指令的处理目标 二、工程设置 三、程序改进 四、下载与调试 1、合规的指令 2、 proBuffer[0]不是# 3、proBuffer[4]不是; 4、指令长度小于5 5、指令长度大于5 6、proBuffer[2]或proBuffer[3]不是数字 7、;位于p…...

无人机场景 - 目标检测数据集 - 夜间车辆检测数据集下载「包含VOC、COCO、YOLO三种格式」

数据集介绍&#xff1a;无人机场景夜间车辆检测数据集&#xff0c;真实场景高质量图片数据&#xff0c;涉及场景丰富&#xff0c;比如夜间无人机场景城市道路行驶车辆图片、夜间无人机场景城市道边停车车辆图片、夜间无人机场景停车场车辆图片、夜间无人机场景小区车辆图片、夜…...

Dubbo 构建高效分布式服务架构

一、引言 随着软件系统的复杂性不断增加&#xff0c;传统的单体架构已经难以满足大规模业务的需求。分布式系统架构通过将系统拆分成多个独立的服务&#xff0c;实现了更好的可扩展性、可维护性和高可用性。在分布式系统中&#xff0c;服务之间的通信和协调是一个关键问题&…...

Unity XR Interaction Toolkit 开发教程(1):OpenXR 与 XRI 概述【3.0 以上版本】

文章目录 &#x1f4d5;Unity XR 开发架构&#x1f50d;底层插件&#xff08;对接硬件&#xff09;&#x1f50d;高层 SDK&#xff08;面向应用交互层&#xff09; &#x1f4d5;OpenXR&#x1f4d5;XR Interaction Toolkit&#x1f50d;特点&#x1f50d;XRI 能够实现的交互类…...

自扶正救生艇,保障水上救援的安全卫士_鼎跃安全

在应急事件中&#xff0c;自扶正救生艇能够发挥关键的救援和保障作用&#xff0c;确保救援人员和被困人员的生命安全&#xff0c;尤其在极端天气或突发水上事故中展现出明显优势。 在救援过程中如果遭遇翻船&#xff0c;救生艇能够迅速恢复正常姿态&#xff0c;确保救援人员不会…...

《Qwen2-VL》论文精读【下】:发表于2024年10月 Qwen2-VL 迅速崛起 | 性能与GPT-4o和Claude3.5相当

1 前言 《Qwen2-VL》论文精读【上】&#xff1a;发表于2024年10月 Qwen2-VL 迅速崛起 | 性能与GPT-4o和Claude3.5相当 上回详细分析了Qwen2-VL的论文摘要、引言、实验&#xff0c;下面继续精读Qwen2-VL的方法部分。 文章目录 1 前言2 方法2.1 Model Architecture2.2 改进措施2…...

WebSocket消息帧的组成结构

WebSocket消息帧是WebSocket协议中的一个基本单位&#xff0c;它定义了数据在客户端和服务器之间传递的格式。每个数据帧包含了不同类型的数据和各种控制信息。以下是WebSocket消息帧的组成结构&#xff1a; WebSocket 帧结构 FIN、RSV1、RSV2、RSV3 和 opcode&#xff08;第一…...

如何利用低代码开源框架实现高效开发?

随着数字化转型步伐的加快&#xff0c;越来越多的企业开始关注提高软件开发效率的方法。低代码平台因其能够大幅减少编码量而受到欢迎&#xff0c;而开源框架则因其灵活性和社区支持成为开发者的首选。如何利用低代码开源框架实现高效开发&#xff0c;成为许多企业和开发者面临…...

使用 RabbitMQ 有什么好处?

大家好&#xff0c;我是锋哥。今天分享关于【使用 RabbitMQ 有什么好处&#xff1f;】面试题。希望对大家有帮助&#xff1b; 使用 RabbitMQ 有什么好处&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 RabbitMQ 是一种流行的开源消息代理&#xff0c;广…...

机器学习周报(RNN的梯度消失和LSTM缓解梯度消失公式推导)

文章目录 摘要Abstract 1 RNN的梯度消失问题2 LSTM缓解梯度消失总结 摘要 在深度学习领域&#xff0c;循环神经网络&#xff08;Recurrent Neural Network, RNN&#xff09;被广泛应用于处理序列数据&#xff0c;特别是在自然语言处理、时间序列预测等任务中。然而&#xff0c…...

一篇文章理解前端中的 File 和 Blob

概述&#xff1a; js处理文件、二进制数据和数据转换的时候&#xff0c;提供了一些API和对象&#xff0c;例如&#xff1a;File、Blob、FileReader、ArraryBuffer、Base64、Object URL 和 DataURL。现在主要介绍File和Blob这两个对象。 1.Blob介绍 在js中&#xff0c;Blob&am…...

串口屏控制的自动滑轨(未完工)

序言 疫情期间自己制作了一个自动滑轨&#xff0c;基于无线遥控的&#xff0c;但是整体太大了&#xff0c;非常不方便携带&#xff0c;所以重新设计了一个新的&#xff0c;以2020铝型材做导轨的滑轨&#xff0c;目前2020做滑轨已经很成熟了&#xff0c;配件也都非常便宜&#x…...

DFA算法实现敏感词过滤

DFA算法实现敏感词过滤 需求&#xff1a;检测一段文本中是否含有敏感词。 比如检测一段文本中是否含有&#xff1a;“滚蛋”&#xff0c;“滚蛋吧你”&#xff0c;“有病”&#xff0c; 可使用的方法有&#xff1a; 遍历敏感词&#xff0c;判断文本中是否含有这个敏感词。 …...

Python自动化运维:技能掌握与快速入门指南

#编程小白如何成为大神&#xff1f;大学生的最佳入门攻略# 在当今快速发展的IT行业中&#xff0c;Python自动化运维已经成为了一个不可或缺的技能。本文将为您详细介绍Python自动化运维所需的技能&#xff0c;并提供快速入门的资源&#xff0c;帮助您迅速掌握这一领域。 必备…...

在linux系统中安装pygtftk软件

1.下载和安装 网址&#xff1a; https://dputhier.github.io/pygtftk/index.html ## 手动安装 git clone http://gitgithub.com:dputhier/pygtftk.git pygtftk cd pygtftk # Check your Python version (>3.8,<3.9) pip install -r requirements.txt python setup.py in…...

decodeURIComponentSafe转义%问题记录URI malformed

decodeURIComponentSafe转义%问题记录 问题背景 当我们解析包涵 % 字符的字符串时&#xff0c;会出现错误如下 Uncaught URIError: URI malformed 解决方案&#xff1a; function decodeURIComponentSafe(s) {if (!s) {return s;}return decodeURIComponent(s.replace(/%(?…...

自由学习记录(18)

动画事件的碰撞器触发 Physics 类的常用方法 RaycastHit hit; if (Physics.Raycast(origin, direction, out hit, maxDistance)) {Debug.Log("Hit: " hit.collider.name); } Physics.Raycast&#xff1a;从指定点向某个方向发射射线&#xff0c;检测是否与碰撞体…...

vue3-ref 和 reactive

文章目录 vue3 中 ref 和 reactivereactive 与 ref 不同之处ref 处理复杂类型ref在dom中的应用 vue3 中 ref 和 reactive ref原理 基本原理 ref是Vue 3中用于创建响应式数据的一个函数。它的基本原理是通过Object.defineProperty()&#xff08;在JavaScript的规范中用于定义对…...

Apache Calcite - 查询优化之自定义优化规则

RelOptRule简介 为了自定义优化规则&#xff0c;我们需要继承RelOptRule类。org.apache.calcite.plan.RelOptRule 是 Apache Calcite 中的一个抽象类&#xff0c;用于定义优化规则。优化规则是用于匹配查询计划中的特定模式&#xff0c;并将其转换为更优化的形式的逻辑。通过继…...

大型语言模型(LLM)的小型化研究进展

2024年&#xff0c;大型语言模型&#xff08;LLM&#xff09;的小型化研究取得了显著进展&#xff0c;主要采用以下几种方法实现&#xff1a; 模型融合&#xff1a;通过将多个模型或检查点合并为一个单一模型&#xff0c;减少资源消耗并提升整体性能。例如&#xff0c;《WARM: …...

MiniWord

1.nuget 下载配置 2.引用 3. var value = new Dictionary<string, object>() { ["nianfen"] = nianfen, ["yuefen"] = yuefen, ["yuefenjian1"] = (int.Par…...

Netty 常见组件介绍

Netty 常见组件介绍 上篇文章Netty入门程序echo 基本包含了Netty常见的组件&#xff0c;本文分别介绍各个组件 Bootstrap or ServerBootstrapEventLoopEventLoopGroupChannelPipelineChannelFuture or ChannelFutureChannelInitializerChannelHandler Bootstrap vs ServerBo…...

高频电子线路---倍频器与振荡器

目录 倍频电路原理 丙类倍频器原理电路 问题: 提升滤波方法: 导通角 振荡器 振荡器基本工作原理 首先是怎么维持 那么如何振荡呢? 思考题: 组成要素 振荡器的起振条件 平衡条件 要点提示 稳定条件 振幅平衡 硬激励起振时: 稳定条件 相位平衡 倍频电路原理 简单原理 : …...

删除 git submodule

直接运行下面命令即可&#xff1a; git rm <path-to-submodule>然后提交修改即可。 但是&#xff0c;还有一个小问题&#xff1a;上面命令只是将 submodule 的代码目录删除了。 以下痕迹还存在你的仓库中&#xff1a; .gitmodule 中关于该 submodule 的信息.git 目录…...

el-table 多选默认选中(根据返回的id给数据加默认选中状态)

前言 el-table是我们最常用的展示数据的方式&#xff0c;但是有时候需要用到多选来选择数据&#xff0c;新增数据的时候还好&#xff0c;选中状态都是正常的&#xff0c;但是修改就遇到问题&#xff0c;需要对这个已经选择过的数据加上默认的选中状态&#xff0c;本次就是解决…...

境外网站翻译之自由职业

Polls Do you use AI tools (e.g ChatGPT, Midjourney, Github Copilot) as part of your work? 你在工作中会使用人工智能工具&#xff08;如 ChatGPT、Midjourney、Github Copilot&#xff09;吗&#xff1f; Yes, as an assistant 是的&#xff0c;作为一种辅助工具。 Y…...

批量图片转PDF文件的多种方法详解

要将批量图片转换为PDF文件&#xff0c;可以使用多种方法&#xff0c;包括使用在线工具、桌面应用程序或编程语言。以下是几种常见的方法&#xff1a; 方法一&#xff1a;使用在线工具 选择工具&#xff1a;搜索“图片转PDF”在线工具&#xff0c;如 Smallpdf、ILovePDF 等。…...

Web服务器(理论)

目录 Web服务器www简介常见Web服务程序介绍&#xff1a;服务器主机主要数据浏览器 网址及HTTP简介URLhttp请求方法:2.3 HTTP协议请求的工作流程&#xff1a; www服务器的类型静态网站动态网站 快速安装Apache安装准备工作httpd所需目录主配置文件 nignx安装1、安装2、准备工作 …...

js:()=>(,);()的作用:明确表达式的边界。

()>{表达式1&#xff1b;表达式2&#xff1b;表达式3&#xff1b;... return 结果} 等同于 ()>(表达式1,表达式2,表达式3,... 结果&#xff09; 例子&#xff1a; const strarr [a, b, c];const result strarr.reduce((acc, curr) > {(acc[curr] 1);console.lo…...

RSI 5G通信技术中用于标识小区的特定参数

RSI是指在5G通信技术中用于标识小区的特定参数&#xff0c;全称为Radio Subframe Indicator&#xff08;无线子帧指示符&#xff09;。在原文的上下文中&#xff0c;RSI被用来确保相邻小区间有足够的间隔&#xff0c;避免由于RSI冲突导致用户设备&#xff08;UE&#xff09;随机…...