当前位置: 首页 > 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: …...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

嵌入式学习笔记DAY33(网络编程——TCP)

一、网络架构 C/S &#xff08;client/server 客户端/服务器&#xff09;&#xff1a;由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序&#xff0c;负责提供用户界面和交互逻辑 &#xff0c;接收用户输入&#xff0c;向服务器发送请求&#xff0c;并展示服务…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)

目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 &#xff08;1&#xff09;输入单引号 &#xff08;2&#xff09;万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...

第八部分:阶段项目 6:构建 React 前端应用

现在&#xff0c;是时候将你学到的 React 基础知识付诸实践&#xff0c;构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段&#xff0c;你可以先使用模拟数据&#xff0c;或者如果你的后端 API&#xff08;阶段项目 5&#xff09;已经搭建好&#xff0c;可以直接连…...

Java后端检查空条件查询

通过抛出运行异常&#xff1a;throw new RuntimeException("请输入查询条件&#xff01;");BranchWarehouseServiceImpl.java // 查询试剂交易&#xff08;入库/出库&#xff09;记录Overridepublic List<BranchWarehouseTransactions> queryForReagent(Branch…...

医疗AI模型可解释性编程研究:基于SHAP、LIME与Anchor

1 医疗树模型与可解释人工智能基础 医疗领域的人工智能应用正迅速从理论研究转向临床实践,在这一过程中,模型可解释性已成为确保AI系统被医疗专业人员接受和信任的关键因素。基于树模型的集成算法(如RandomForest、XGBoost、LightGBM)因其卓越的预测性能和相对良好的解释性…...