一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何高效解析不定長度的協(xié)議幀?

STM32嵌入式開發(fā) ? 來源:CSDN-RimeLink ? 2023-07-18 16:09 ? 次閱讀

通信設(shè)計(jì)中考慮協(xié)議的靈活性,經(jīng)常把協(xié)議設(shè)計(jì)成“不定長度”。一個(gè)實(shí)例如下圖:銳米LoRa終端的通信協(xié)議幀。
bc5c5e50-2541-11ee-962d-dac502259ad0.jpg ????

如果一個(gè)系統(tǒng)接收上述“不定長度”的協(xié)議幀,將會(huì)有一個(gè)挑戰(zhàn)--如何高效接收與解析。

為簡化系統(tǒng)設(shè)計(jì),我們強(qiáng)烈建議您采用“狀態(tài)機(jī)”來解析UART數(shù)據(jù)幀,并且把解析工作放在ISR(中斷服務(wù)程序)完成,僅當(dāng)接收到最后一個(gè)字節(jié)(0x0D)時(shí),再將整個(gè)數(shù)據(jù)幀提交給進(jìn)程處理。該解析狀態(tài)機(jī)的原理如下圖所示:
bc6eafba-2541-11ee-962d-dac502259ad0.jpg ????

那么ISR處理這個(gè)狀態(tài)機(jī)來得及嗎?答案是:so easy!因?yàn)樗挥?個(gè)動(dòng)作,運(yùn)算量十分?。?br />
比較接收數(shù)據(jù) -> 更新狀態(tài)變量 -> 存儲(chǔ)接收數(shù)據(jù),C語言僅3條語句,翻譯成機(jī)器指令也不超過10條。

代碼清單如下:

/**
* @brief  Status of received communication frame
*/
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;


/**
* @brief  Data object for received communication frame
*/
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;






/**


* @brief  Data object for received communication frame.
* @note  Prevent race condition that accessed by both ISR and process.
*/
static COMM_TRM_DATA    s_stComm2TrmData;






/**
  * @brief  Put a data that received by UART into buffer.
  * @note  Prevent race condition this called by ISR. 
  * @param  uint8_t byData: the data received by UART.
  * @retval  None
  */
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);
            }
            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; 
}

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 通信協(xié)議
    +關(guān)注

    關(guān)注

    28

    文章

    975

    瀏覽量

    40854
  • 狀態(tài)機(jī)
    +關(guān)注

    關(guān)注

    2

    文章

    493

    瀏覽量

    27970
  • 通信設(shè)計(jì)
    +關(guān)注

    關(guān)注

    0

    文章

    26

    瀏覽量

    10602
  • LoRa
    +關(guān)注

    關(guān)注

    351

    文章

    1744

    瀏覽量

    234018

原文標(biāo)題:如何高效解析不定長度的協(xié)議幀?

文章出處:【微信號(hào):c-stm32,微信公眾號(hào):STM32嵌入式開發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    如何使用DMA進(jìn)行USART不定長度接收

    在上一講中,我們對(duì)USART進(jìn)行了簡單介紹,并講解了如何在不使用DMA的情況下進(jìn)行不定長度數(shù)據(jù)接收,本講將著重講解如何使用DMA進(jìn)行USART不定長度接收。
    的頭像 發(fā)表于 02-18 17:01 ?690次閱讀
    如何使用DMA進(jìn)行USART<b class='flag-5'>不定長度</b>接收

    用串口DMA傳輸不定長度包的方式

    經(jīng)??吹接腥嗽趩栍肈MA接收不定長包的問題,由于STM32DMA的特殊性,使其對(duì)接收不定長的數(shù)據(jù)不太方便,很多人都在為此傷腦筋,也有不少牛人想了不少的辦法,例如用協(xié)議或開定時(shí)器判別等,其實(shí)這些方法都
    發(fā)表于 12-26 08:48

    STM32單片機(jī)接收不定長度字節(jié)數(shù)據(jù)的方法解析相關(guān)資料推薦

    http://m.elecfans.com/article/899756.html今天說一下STM32單片機(jī)的接收不定長度字節(jié)數(shù)據(jù)的方法。由于STM32單片機(jī)帶IDLE中斷,所以利用這個(gè)中斷,可以
    發(fā)表于 07-01 09:41

    STM32單片機(jī)的接收不定長度字節(jié)數(shù)據(jù)的方法

    STM32串口使用IDLE中斷接收不定長數(shù)據(jù)原理與源程序轉(zhuǎn)載 2016年07月16日 18:20:24原文來自 今天說一下STM32單片機(jī)的接收不定長度字節(jié)數(shù)據(jù)的方法。由于STM32單片機(jī)帶IDLE中斷,所以利用這個(gè)中斷,可以接收不定長
    發(fā)表于 08-04 09:05

    stm32串口是如何實(shí)現(xiàn)接收不定長度數(shù)據(jù)的呢

    stm32串口是如何實(shí)現(xiàn)接收不定長度數(shù)據(jù)的呢?串口接收數(shù)據(jù)一般會(huì)采用串口中斷方式自動(dòng)接收,要想接收不定長度數(shù)據(jù),就需要讓單片機(jī)在接收完成一數(shù)據(jù)之后,自動(dòng)告知系統(tǒng)數(shù)據(jù)已經(jīng)接收完成了,這個(gè)過程其實(shí)都是
    發(fā)表于 08-11 08:18

    STM32串口接收不定長數(shù)據(jù)

    STM32串口接收不定長數(shù)據(jù)->鏈表數(shù)據(jù)說明二級(jí)目錄三級(jí)目錄數(shù)據(jù)說明STM32數(shù)據(jù)寄存器為USARTx->DR寄存器二級(jí)目錄三級(jí)目錄
    發(fā)表于 12-06 07:05

    STM32 HAL DMA串口接收不定長度的實(shí)現(xiàn)方法

    STM32 HAL DMA串口接收不定長度的實(shí)現(xiàn)方法
    發(fā)表于 12-08 07:59

    STM32 Uart是如何接收不定長度的數(shù)據(jù)呢

    我們?nèi)绾未_定數(shù)據(jù)包的長度?STM32 Uart是如何接收不定長度的數(shù)據(jù)呢?
    發(fā)表于 12-09 06:12

    STM32單片機(jī)的接收不定長度字節(jié)數(shù)據(jù)的方法

    來說一下STM32單片機(jī)的接收不定長度字節(jié)數(shù)據(jù)的方法。由于STM32單片機(jī)帶IDLE中斷,所以利用這個(gè)中斷,可以接收不定長字節(jié)的數(shù)據(jù),由于STM32屬于ARM單片機(jī),所以這篇文章的方法也適合其他
    發(fā)表于 01-06 08:04

    利用STM32F1的串口空閑中斷實(shí)現(xiàn)不定長的數(shù)據(jù)斷

    常見的數(shù)據(jù)方式有兩種,一種是通過固定的協(xié)議格式斷,另外一個(gè)是通過兩幀數(shù)據(jù)的時(shí)間斷,下面介紹最后一種,利用STM32F1的串口空閑中
    發(fā)表于 02-17 07:55

    C語言中怎么定義一個(gè)不定長度的數(shù)組?

    C語言中怎么定義一個(gè)不定長度的數(shù)組
    發(fā)表于 10-09 07:40

    STM32串口通信 (采用鏈表接收不定長數(shù)據(jù))

    STM32串口接收不定長數(shù)據(jù)->鏈表數(shù)據(jù)說明二級(jí)目錄三級(jí)目錄數(shù)據(jù)說明STM32數(shù)據(jù)寄存器為USARTx->DR寄存器二級(jí)目錄三級(jí)目錄
    發(fā)表于 11-23 18:07 ?31次下載
    STM32串口通信 (采用鏈表接收<b class='flag-5'>不定長</b>數(shù)據(jù)<b class='flag-5'>幀</b>)

    stm32 串口接收不定長度數(shù)據(jù)及黏包處理 + 串口DMA接收

    ,那么stm32串口是如何實(shí)現(xiàn)接收不定長度數(shù)據(jù)的呢? 串口接收數(shù)據(jù)一般會(huì)采用串口中斷方式自動(dòng)接收,要想接收不定長度數(shù)據(jù),就需要讓單片機(jī)在接收完成一數(shù)據(jù)之后,自動(dòng)告知系統(tǒng)數(shù)據(jù)已經(jīng)接收完成了,這個(gè)過程其實(shí)
    發(fā)表于 12-23 19:09 ?27次下載
    stm32 串口接收<b class='flag-5'>不定長度</b>數(shù)據(jù)及黏包處理 + 串口DMA接收

    單片機(jī)的通信協(xié)議該如何設(shè)計(jì)

    ????通信設(shè)計(jì)中考慮協(xié)議的靈活性,經(jīng)常把協(xié)議設(shè)計(jì)成“不定長度”。 一個(gè)實(shí)例如下圖:銳米LoRa終端的通信協(xié)議。 ????如果一個(gè)系統(tǒng)接收
    的頭像 發(fā)表于 07-05 17:19 ?2317次閱讀

    如何采用“狀態(tài)機(jī)”解析UART數(shù)據(jù)

    如果一個(gè)系統(tǒng)接收上述“不定長度”的協(xié)議,將會(huì)有一個(gè)挑戰(zhàn)--如何高效接收與解析。 為簡化系統(tǒng)設(shè)計(jì),我們強(qiáng)烈建議您采用“狀態(tài)機(jī)”來
    的頭像 發(fā)表于 03-25 14:29 ?989次閱讀
    如何采用“狀態(tài)機(jī)”<b class='flag-5'>解析</b>UART數(shù)據(jù)<b class='flag-5'>幀</b>