通信设计中考虑协议的灵活性,经常把协议设计成“不定长度”。一个实例如下图:锐米LoRa终端的通信协议帧。
如果一个系统接收上述“不定长度”的协议帧,将会有一个挑战--如何高效接收与解析。 为简化系统设计,我们强烈建议您采用“状态机”来解析UART数据帧,并且把解析工作放在ISR(中断服务程序)完成,仅当接收到最后一个字节(0x0D)时,再将整个数据帧提交给进程处理。 该解析状态机的原理如下图所示:
那么ISR处理这个状态机来得及吗?答案是:so easy!因为它只有3个动作,运算量十分小: 比较接收数据 -> 更新状态变量 -> 存储接收数据,C语言仅3条语句,翻译成机器指令也不超过10条。
代码清单如下:
/** *@briefStatusofreceivedcommunicationframe */ typedefenum { STATUS_IDLE=(uint8_t)0, STATUS_HEAD,/*RxHead=0x3C*/ STATUS_TYPE,/*RxType*/ STATUS_DATA,/*Datafiled*/ STATUS_TAIL,/*Tail=0x0D*/ STATUS_END,/*Endofthisframe*/ }COMM_TRM_STATUS_TypeDef; /** *@briefDataobjectforreceivedcommunicationframe */ typedefstruct { uint8_tbyCnt;/*Countof1field*/ uint8_tbyDataLen;/*Lengthofdatafield*/ uint8_tbyFrameLen;/*Lengthofframe*/ COMM_TRM_STATUS_TypeDefeRxStatus; uint8_ta_byRxBuf[MAX_LEN_COMM_TRM_DATA]; }COMM_TRM_DATA; /** *@briefDataobjectforreceivedcommunicationframe. *@notePreventraceconditionthataccessedbybothISRandprocess. */ staticCOMM_TRM_DATAs_stComm2TrmData; /** *@briefPutadatathatreceivedbyUARTintobuffer. *@notePreventraceconditionthiscalledbyISR. *@paramuint8_tbyData:thedatareceivedbyUART. *@retvalNone */ voidcomm2trm_RxUartData(uint8_tbyData) { /*Updatestatusaccordingtothereceiveddata*/ switch(s_stComm2TrmData.eRxStatus) { caseSTATUS_IDLE: if(COMM_TRM_HEAD==byData)/*IsHead*/ { s_stComm2TrmData.eRxStatus=STATUS_HEAD; } else { gotorx_exception; } break; caseSTATUS_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); } else { goto rx_exception; } break; default: ASSERT(!"Error: Bad status of comm2trm_RxUartData(). "); break; } /* Save the received data */ s_stComm2TrmData.a_byRxBuf[s_stComm2TrmData.byFrameLen++] = byData; return; rx_exception: ClearCommFrame(); return; }审核编辑:黄飞
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
-
状态机
+关注
关注
2文章
486浏览量
27182 -
数据帧
+关注
关注
0文章
33浏览量
6647 -
csdn
+关注
关注
2文章
16浏览量
6819
原文标题:状态机”来解析UART不定长度的协议帧
文章出处:【微信号:嵌入式情报局,微信公众号:嵌入式情报局】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
状态机编程
状态机编程基于状态机的按键输入软件接口设计一般的教课书中给出的按键输入软件接口程序通常非常简单,在程序中一旦检测到按键输入口为低电平时(图9-2),便采用(调用)软件延时程序延时10ms。然后再
发表于 07-10 18:00
如何写好状态机
一篇经典文献,详细讲解了一段、两段、三段式状态机的实现,效率、优缺点。看完后相信会对状态机有一个详细的了解。 状态机是逻辑设计的重要内容,状态机的设计水平直接反应工程师的逻辑功底,所以
发表于 10-24 11:43
raw os 之状态机编程
事件的操作系统QP 具有异曲同工之妙。状态机编程的其中一个优势是所有的任务可以共享一个栈,这样可以避免传统的操作系统一个任务一个栈空间的局限。所以能普遍被资源短缺的单片机系统采用,另外一个优势是面对复杂
发表于 02-27 14:35
状态机问题
fpga中传输数据流,帧格式的,每行有起始字节(SAV)和终止字节(EAV),其实就是BT656格式的,如何写状态机判断数据流传输过程中被中断了?求给个思路
发表于 08-20 17:33
ISR状态机超时
大家好,芯片是PIC18F46K22,使用XC8编译器。我在UART RX中断处理程序中有一个简单的状态机。它每隔几秒钟从另一个设备接收一个10字节的数据包。我想检测另一个设备不发送完整的10字节
发表于 11-27 15:05
什么是状态机
一. 什么是状态机我们以生活中的小区的停车系统为例:停车杆一般没车的是不动的(初态),有车来的时候需要抬杆(状态1),车通过需要放杆(状态2),如果在放杆的过程中突然有车,又需要抬杆(状态
发表于 01-06 08:01
什么是状态机
目录1 前言2 状态机2.1 什么是状态机2.2 状态机的概念2.3 使用状态机写键盘的思路3 代码实例3.1 使用软件3.2 protues电路图3.2
发表于 01-24 06:23
什么是状态机?状态机的种类与实现
状态机,又称有限状态机(Finite State Machine,FSM)或米利状态机(Mealy Machine),是一种描述系统状态变化的模型。在芯片设计中,
评论