• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 新聞中心

    EEPW首頁 > 嵌入式系統 > 設計應用 > 單片機通信協議處理

    單片機通信協議處理

    作者: 時間:2012-10-26 來源:網絡 收藏

    以下給出具體的實例。在這個系統中,串口的命令非常簡單。所有的全部在串口中斷中進行。數據包的格式如下:

    0x55, 0xAA, 0x7E, 0x12, 0xF0, 0x02, 0x23, 0x45, SUM, XOR, 0x0D

    其中0x55, 0xAA, 0x7E為數據幀的幀頭,0x0D為幀尾,0x12為設備的目的地址,0xF0為源地址,0x02為數據長度,后面接著兩個數據0x23, 0x45,從目的地址開始結算累加、異或校驗和,到數據的最后一位結束。

    解析的目的,首先判斷數據包的完整性,正確性,然后提取數據類型,數據等數據,存放起來用于主程序。代碼如下:

    if(state_machine == 0) // 解析狀態機

    {

    if(rcvdat == 0x55) // 接收到幀頭第一個數據

    state_machine = 1;

    else

    state_machine = 0; // 狀態機復位

    }

    else if(state_machine == 1)

    {

    if(rcvdat == 0xAA) // 接收到幀頭第二個數據

    state_machine = 2;

    else

    state_machine = 0; // 狀態機復位

    }

    else if(state_machine == 2)

    {

    if(rcvdat == 0x7E) // 接收到幀頭第三個數據

    state_machine = 3;

    else

    state_machine = 0; // 狀態機復位

    }

    else if(state_machine == 3)

    {

    sumchkm = rcvdat; // 開始計算累加、異或校驗和

    xorchkm = rcvdat;

    if(rcvdat == m_SrcAdr) // 判斷目的地址是否正確

    state_machine = 4;

    else

    state_machine = 0;

    }

    else if(state_machine == 4)

    {

    sumchkm += rcvdat;

    xorchkm ^= rcvdat;

    if(rcvdat == m_DstAdr) // 判斷源地址是否正確

    state_machine = 5;

    else

    state_machine = 0;

    }

    else if(state_machine == 5)

    {

    lencnt = 0; // 接收數據計數器

    rcvcount = rcvdat; // 接收數據長度

    sumchkm += rcvdat;

    xorchkm ^= rcvdat;

    state_machine = 6;

    }

    else if(state _machine == 6 || state _machine == 7)

    {

    m_ucData[lencnt++] = rcvdat; // 數據保存

    sumchkm += rcvdat;

    xorchkm ^= rcvdat;

    if(lencnt == rcvcount) // 判斷數據是否接收完畢

    state_machine = 8;

    else

    state_machine = 7;

    }

    else if(state_machine == 8)

    {

    if(sumchkm == rcvdat) // 判斷累加和是否相等

    state_machine = 9;

    else

    state_machine = 0;

    }

    else if(state_machine == 9)

    {

    if(xorchkm == rcvdat) // 判斷異或校驗和是否相等

    state_machine = 10;

    else

    state_machine = 0;

    }

    else if(state_machine == 10)

    {

    if(0x0D == rcvdat) // 判斷是否接收到幀尾結束符

    {

    retval = 0xaa; // 置標志,表示一個數據包接收到

    }

    state_machine = 0; // 復位狀態機

    }

    此過程中,使用了一個變量state_machine作為協議狀態機的轉換狀態,用于確定當前字節處于一幀數據中的那個部位,同時在接收過程中自動對接收數據進行校驗和,在數據包接收完的同時也進行了校驗的比較。因此當幀尾結束符接收到的時候,則表示一幀數據已經接收完畢,并且通過了校驗,關鍵數據也保存到了緩沖去中。主程序即可通過retval的標志位來進行協議的解析

    接收過程中,只要哪一步收到的數據不是預期值,則直接將狀態機復位,用于下一幀數據的判斷,因此系統出現狀態死鎖的情況非常少,系統比較穩定,如果出現丟失數據包的情況也可由上位機進行命令的補發,不過這種情況筆者還沒有碰到。

    對于主程序中進行協議處理的過程與此類似,主程序循環中不斷的讀取串口緩沖區的數據,此數據即參與到主循環中的協議處理過程中,代碼與上面所述完全一樣。



    評論


    相關推薦

    技術專區

    關閉
    主站蜘蛛池模板: 浮梁县| 贵南县| 临沂市| 光山县| 南澳县| 绿春县| 安达市| 张掖市| 海淀区| 晴隆县| 西乡县| 社会| 自治县| 新安县| 安化县| 定陶县| 遂昌县| 吉安市| 宣恩县| 吉安市| 榆中县| 西青区| 东丰县| 全椒县| 南城县| 永仁县| 封丘县| 固镇县| 赞皇县| 浏阳市| 屏东县| 霍山县| 藁城市| 黄梅县| 乌恰县| 水城县| 辽阳县| 朝阳市| 任丘市| 榆树市| 应用必备|