0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何采用“状态机”解析UART数据帧

嵌入式情报局 来源:csdn 2024-03-25 14:29 次阅读

通信设计中考虑协议的灵活性,经常把协议设计成“不定长度”。一个实例如下图:锐米LoRa终端的通信协议帧。

f914fa00-e855-11ee-a297-92fbcf53809c.jpg

如果一个系统接收上述“不定长度”的协议帧,将会有一个挑战--如何高效接收与解析。 为简化系统设计,我们强烈建议您采用“状态机”来解析UART数据帧,并且把解析工作放在ISR(中断服务程序)完成,仅当接收到最后一个字节(0x0D)时,再将整个数据帧提交给进程处理。 该解析状态机的原理如下图所示:

f91c6556-e855-11ee-a297-92fbcf53809c.jpg

那么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不定长度的协议帧

文章出处:【微信号:嵌入式情报局,微信公众号:嵌入式情报局】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    采用米利型的状态机电路设计

    首先可以确定采用米利型状态机设计该电路。因为该电路在连续收到信号0101时,输出为1,其他情况下输出为0,所以采用米利型状态机
    的头像 发表于 09-08 14:06 7539次阅读
    <b class='flag-5'>采用</b>米利型的<b class='flag-5'>状态机</b>电路设计

    状态机编程

    状态机编程基于状态机的按键输入软件接口设计一般的教课书中给出的按键输入软件接口程序通常非常简单,在程序中一旦检测到按键输入口为低电平时(图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

    队列状态机

    应用LabView做的连接mdb数据库,应用队列状态机
    发表于 02-05 22:58

    【FPGA】UART内核模块的状态机如何设计

    UART 内核模块的状态机设计UART 内核模块的功能是控制数据接收、数据加载和数据发送的过程,
    发表于 10-24 10:06

    ISR状态机超时

    大家好,芯片是PIC18F46K22,使用XC8编译器。我在UART RX中断处理程序中有一个简单的状态机。它每隔几秒钟从另一个设备接收一个10字节的数据包。我想检测另一个设备不发送完整的10字节
    发表于 11-27 15:05

    状态机是什么?什么是消息触发类型的状态机

    状态机可归纳为哪几个要素?状态机可分为哪几种?什么是消息触发类型的状态机
    发表于 04-19 06:02

    什么是状态机状态机是如何编程的?

    什么是状态机状态机是如何编程的?
    发表于 10-20 07:43

    什么是状态机

    一. 什么是状态机我们以生活中的小区的停车系统为例:停车杆一般没车的是不动的(初态),有车来的时候需要抬杆(状态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

    采用状态机和消息机制的串口接收程序

    采用状态机和消息机制的串口接收程序
    发表于 05-16 14:51 48次下载

    FPGA:状态机简述

    本文目录 前言 状态机简介 状态机分类 Mealy 型状态机 Moore 型状态机 状态机描述 一段式
    的头像 发表于 11-05 17:58 6236次阅读
    FPGA:<b class='flag-5'>状态机</b>简述

    什么是状态机状态机的种类与实现

    状态机,又称有限状态机(Finite State Machine,FSM)或米利状态机(Mealy Machine),是一种描述系统状态变化的模型。在芯片设计中,
    的头像 发表于 10-19 10:27 5067次阅读