日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

mfc如何将一个数组中的字节数据用串口发送出去_[翻译] 串口通信的帧(frame)...

發布時間:2024/4/11 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mfc如何将一个数组中的字节数据用串口发送出去_[翻译] 串口通信的帧(frame)... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在串口通信中,只傳輸一個字節是簡單的,但是如果要傳送一個幀(多個字節),將面臨以下問題:

  • receiver從串口接收的是字節流,那它是如何知道幀的開始或結束呢?它又是如何知道這個幀有多長?
  • 真實的物理硬件是充滿噪音和干擾的,由于電噪聲,某些字節的位可能被翻轉,字節甚至整個幀都可能會丟失。

要解決這些問題,首先需要了解下計算機網絡中數據鏈路層的基礎知識。

基于一個可以在設備之間傳輸信號的物理層,數據鏈路層的工作(粗略地說)就是傳輸整個數據幀,其中一些方法可以確保數據的完整性(減少錯誤)。當我們使用socket通過TCP或UDP進行網絡通信時,幀在硬件層面得到了很好的處理,以至于上層甚至都感覺不到。但是,在串口通信中,我們必須自己處理幀和數據錯誤。

處理幀有以下幾種方法:

  • 在幀之間插入時間間隔
  • 物理層coding violations
  • 字符計數
  • 帶字節填充的flag bytes
  • 帶位填充的flag bytes
  • 方法1和2僅適用于硬件實現的數據鏈路層。當涉及多層軟件(比如在Windows上運行)時,確保計時非常困難。

    方法3的意思是在幀頭中指定幀中的字節數。這樣做的問題是計數可能因傳輸錯誤而出現亂碼。在這種情況下,“重新同步”會非常困難,因而這種方法很少使用。

    方法4和5有些相似。在本文中,我將重點關注4,因為5不適合串口通信。

    帶字節填充的標志字節

    讓我們從先一個簡單的想法開始,然后逐步將其發展成一個完整,強大的方案。flag bytes是特殊字節值,表示幀何時開始和結束。假設我們希望能夠發送任意長度的幀。特殊的start flag bytes表示幀的開始,end flag bytes表示幀的結束。

    那么問題來了。假設end flag的值是0x98,如果0x98又正好出現在data的某處,協議將混淆并認為這個幀到data里的這個0x98就結束了。這個問題有一個簡單的解決辦法,所有熟悉字符串轉義引號和特殊字符的程序員都應該能想到。它被稱為字節填充,或簡單地轉義,具體方法如下:

    每當數據中出現一個flag byte(開始或結束)時,我們將在它之前插入一個特殊的轉義字節(比如ESC)。 當receiver看到ESC時,它知道忽略它并且不將其插入到接收的實際數據中。每當ESC本身必須出現在數據中時,另一個ESC就會被置于其前面。Receiver移除第一個但保留第二個。

    這里有一些示例:

    此外,我們還需要某種錯誤檢查,比如checksum,或者更好的CRC。這通常是幀的最后一個字節,檢查范圍包括幀中的所有字節(以其未填充的形式)。

    這種方案是穩健的:任何丟失的字節(無論是標志,轉義,數據字節還是校驗和字節)都會導致receiver僅丟失一幀,之后它將重新同步到下一幀的start flag。

    PPP協議

    事實上,這種方法可以算是點對點協議(PPP)的簡化版,在PPP中:

    • 開始和結束的flag byte都是0x7E
    • 轉義字節為0x7D
    • 只要消息中出現標志或轉義字節,它就會被0x7D轉義,字節本身與0x20進行異或運算,例如0x7E變為0x7D 0x5E,0x7D變為0x7D 0x5D。Receiver取消轉義轉義字節并再次使用0x20對下一個字節進行異或,以獲得原始數據。

    讓我們用一個完整的例子來演示它是如何工作的。

    假設我們定義以下協議:

    start flag:0x12 end flag:0x13 轉義字節:0x7D

    并且sender想要發送以下數據消息。原始數據在(a)中:

    數據包含兩個需要轉義的標志,位置2的0x13(對,從0開始計數),以及位置4的0x7D。

    Sender的數據鏈路層會將數據轉換為(b)中所示的幀。

    接下來讓我們看看receiver如何處理這樣的幀。 為了演示,假設receiver從串口獲取的第一個字節不是消息的真實部分(我們想看看它如何處理這種情況)。 在下圖中,receiver state是接收字節后receiver的狀態,data buffer是接收數據的緩沖區,用于之后將數據傳遞到上層應用程序。

    有幾點需要注意:

    • 忽略start flag之前的“雜散”字節:根據協議,每個幀必須以start flag開頭,因此這不是幀的一部分。
    • start flag和end flag本身不會進入數據緩沖區。
    • 轉義字節由一特殊狀態AFTER_ESC處理。
    • 當幀以end flag結束時,receiver擁有了一個可以往上層程序傳遞的幀,并且返回等待start flag,或者說等待一個新的幀。

    最后,上層應用程序看到收到的消息正是發送的消息,所有協議細節(標志,轉義等)都由數據鏈路層透明地處理掉了。

    本文翻譯自 https://eli.thegreenplace.net/2009/08/12/framing-in-serial-communications

    原創翻譯,轉載請注明出處。

    總結

    以上是生活随笔為你收集整理的mfc如何将一个数组中的字节数据用串口发送出去_[翻译] 串口通信的帧(frame)...的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。