【“状态机” 解析UART不定长度的协议帧】

【“状态机” 解析UART不定长度的协议帧】

  • 1. 数据帧格式
  • 2. 状态机原理
  • 3. 代码实现

通信设计中考虑协议的灵活性,经常把协议设计成“不定长度”。如果一个系统接收上述“不定长度”的协议帧,将会有一个挑战–如何高效接收与解析。一个实例如下图:米LoRa终端的通信协议帧。

为简化系统设计,我们强烈建议您采用“状态机”来解析UART数据帧,并且把解析工作放在ISR(中断服务程序)完成,仅当接收到最后一个字节(0x0D)时,再将整个数据帧提交给进程处理。

那么ISR处理这个状态机来得及吗?答案是:so easy!因为它只有3个动作,运算量十分小:

比较接收数据 -> 更新状态变量 -> 存储接收数据,C语言仅3条语句,翻译成机器指令也不超过10条。

1. 数据帧格式

在这里插入图片描述

2. 状态机原理

在这里插入图片描述

3. 代码实现

comm2trm_RxUartData()函数放在你的串口中断函数中:

// 变量定义#define MAX_LEN_COMM_TRM_DATA 12     // 单包最长数据长度
#define MAX_LEN_UART_FRAME_DATA 12    // 有效数据长度
#define COMM_TRM_HEAD 0x3C             //帧头
#define COMM_TRM_TAIL 0x0d             // 帧尾
#define TYPE_INVALID_MIN  0x01          // 帧种类起始
#define TYPE_INVALID_MAX  0x0a           // 帧种类结束
typedef enum
{STATUS_IDLE = (uint8_t)0,STATUS_HEAD, /* Rx Head=0x3C */STATUS_TYPE, /* Rx Type */STATUS_DATA, /* Data filed */STATUS_TAIL, /* Tail=0x0D */STATUS_END, /* End of this frame */
} COMM_TRM_STATUS_TypeDef;typedef struct
{uint8_t    byCnt;       /* Count of 1 field */uint8_t    byDataLen; /* Length of data field */uint8_t    byFrameLen; /* Length of frame */COMM_TRM_STATUS_TypeDef    eRxStatus;uint8_t    a_byRxBuf[MAX_LEN_COMM_TRM_DATA]; 
} COMM_TRM_DATA;static COMM_TRM_DATA    s_stComm2TrmData;// 状态机
void comm2trm_RxUartData(uint8_t byData)
{/* Update status according to the received data */switch (s_stComm2TrmData.eRxStatus){case STATUS_IDLE:if (COMM_TRM_HEAD == byData) /* Is Head */{s_stComm2TrmData.eRxStatus = STATUS_HEAD;}else{goto rx_exception;}break;case STATUS_HEAD:if (TYPE_INVALID_MIN < byData && byData < TYPE_INVALID_MAX) /* Valid type */{s_stComm2TrmData.eRxStatus = STATUS_TYPE;}else{goto rx_exception;}break;case STATUS_TYPE:if (byData <= MAX_LEN_UART_FRAME_DATA) /* Valid data size */{s_stComm2TrmData.eRxStatus = STATUS_DATA;s_stComm2TrmData.byDataLen = byData;}else{goto rx_exception;}break;case STATUS_DATA:if (s_stComm2TrmData.byCnt < s_stComm2TrmData.byDataLen){++s_stComm2TrmData.byCnt;}else{s_stComm2TrmData.eRxStatus = STATUS_TAIL;}break;case STATUS_TAIL:if (COMM_TRM_TAIL == byData){/* We received a frame of data, now tell process to deal with it! *///process_poll(&Comm2TrmProcess);printf("frame is over \r\n");}else{goto rx_exception;}break;default:printf("Error: Bad status of comm2trm_RxUartData().\r\n");break;}/* Save the received data */s_stComm2TrmData.a_byRxBuf[s_stComm2TrmData.byFrameLen++] = byData;return;rx_exception://ClearCommFrame();return; 
}

参考资源

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

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

相关文章

【蓝桥杯嵌入式】11届程序题刷题记录及反思

一、题目介绍 按键输入&#xff1a;短按 模拟电压输出&#xff1a;ADC LCD显示 PWM输出&#xff1a;PA6,PA7 二、usr.c #include "usr.h" #include "lcd.h" #include "stdio.h" #include "tim.h" #include "adc.h" /*v…

道本科技智慧合规助力企业转型升级

在当今这个快速变化的商业世界里&#xff0c;企业合规管理已经从一项基本的监管要求转变为推动企业持续发展的关键动力。合规不仅是避免法律麻烦的盾牌&#xff0c;它还充当着引领企业向更高效、更可靠和更可持续方向发展的催化剂。而在实现这一目标的过程中&#xff0c;智慧合…

隐私计算实训营第六讲-隐语PIR介绍及开发实践

隐私计算实训营第六讲-隐语PIR介绍及开发实践 文章目录 隐私计算实训营第六讲-隐语PIR介绍及开发实践1.隐语实现PIR总体介绍1.1按服务器数量分类1.2按查询类型分类 2. Index PIR - SealPIR3. Keyword PIR - Labeled PSI4.隐语PIR功能分层5.隐语PIR后续计划PIR协议开发PIR调用框…

ndk ffmpeg

报错&#xff1a; 解决办法&#xff1a; 报错 解决办法&#xff1a;

干货教程【AI篇】| AI大模型文字生成视频环境部署小白级教程

只需要一个主题、一个词语&#xff0c;或者一段描述&#xff0c;就可以生成一个完整的短视频的工具来啦&#xff01; 在文章下方公众号中回复关键词【aivd】即可获取完整代码和配套软件 工具获取 ps&#xff1a;本文不涉及任何代码开发工作&#xff0c;仅仅作为软件推荐。 如…

洛谷P1000超级玛丽游戏题解[Python, Rust, Go]

题目 打印超级玛丽字符图像 小技巧 直接复制题目的超级玛丽符号首行会有空格问题&#xff0c;一直AC不过&#xff0c;一行一行地复制就OK了&#x1f44c;。 Rust 题解 fn main() {println!(" ********************####....#.#..###.....##....###...…

Linux:冯·诺依曼结构 OS管理机制

Linux&#xff1a;冯诺依曼结构 & OS管理机制 冯诺依曼结构OS管理机制OS对下层硬件的管理OS对上层用户的服务 冯诺依曼结构 我们常见的计算机&#xff0c;比如笔记本&#xff0c;台式电脑。以及一下不常见的计算机&#xff0c;比如服务器&#xff0c;几乎都遵循冯诺依曼体…

element-ui 修改el-form-item样式

文章目录 form结构修改el-form-item所有样式只修改label只修改content只修改input只修改button form结构 <el-form :model"formData" label-width"80px"> <el-form-item label"label1"> <el-input v-model"formData.valu…

深度学习500问——Chapter05: 卷积神经网络(CNN)(4)

文章目录 5.18 卷积神经网络凸显共性的方法 5.18.1 局部连接 5.18.2 权值共享 5.18.3 池化操作 5.19 全连接、局部连接、全卷积与局部卷积 5.20 局部卷积的应用 5.21 NetVLAD池化 参考文献 5.18 卷积神经网络凸显共性的方法 5.18.1 局部连接 我们首先了解一个概念&#xff0c…

2024年03月CCF-GESP编程能力等级认证Scratch图形化编程二级真题解析

本文收录于专栏《Scratch等级认证CCF-GESP真题解析》,专栏总目录・点这里. 一、单选题(共 10 题,每题 3 分,共 30 分) 第1题 小杨的父母最近刚刚给他买了一块华为手表,他说手表上跑的是鸿蒙,这个鸿蒙是?( )。 A、小程序 B、计时器 C、操作系统 D、神话人物 答案:…

【QT学习】4.浮动窗口

结果&#xff1a; 代码&#xff1a; //制作核心控件&#xff1a;文本编辑框QTextEdit* pTextEditnew QTextEdit;//制作浮动控件connect(pMenu1,&QMenu::triggered,[](QAction* pAction){qDebug()<<pAction->text()<<endl;if(pAction->text()"浮动…

俄罗斯Yandex广告推广如何开户及费用?

作为俄罗斯首屈一指的搜索引擎&#xff0c;Yandex凭借其超过60%的市场份额&#xff0c;成为企业进入俄罗斯、触及俄语消费者的关键入口。然而&#xff0c;对于不熟悉当地市场环境与网络营销规则的企业而言&#xff0c;成功开户并高效运营Yandex广告并非易事。云衔科技凭借专业的…