標準CAN幀介紹
- 標準CAN(Controller Area Network)結構
- 1.幀起始(SOF-Start Of Frame)
- 2.仲裁段(Arbitration Field)
- 3.控制段(Control Field)
- 4.數據段(Data Field)
- 5.CRC段(CRC Field)
- 6.應答段(ACK Field)
- 7.結束段(EOF-End Of Frame)
- 8.幀間間隔(IFS-Inter Frame Space)
- 總結與特點
- 具體例子
- 場景設定
- 步驟1:組幀前的準備
- 步驟2:構建標準數據幀
- 步驟3:總線上的傳輸與仲裁過程
- 步驟4:接收與應答過程
- 步驟5數據處理
標準CAN(Controller Area Network)結構
CAN總線通信的核心就是節點間通過發送和接收符合特定格式的“幀”來實現。標準CAN有兩種主要的幀格式:標準幀(11位標識符)和擴展幀(29位標識符)。這里我們首先聚焦于最基礎的標準數據幀。
一個標準CAN數據幀由以下7個不同的位字段(Bit Fields)組成,如下圖所示:
1.幀起始(SOF-Start Of Frame)
- 長度:1 bit
- 值:顯性位(Dominant Bit,邏輯0)
- 作用:標志著數據幀的開始。它同步所有總線上的節點,表示一個新的報文即將開始傳輸。在總線空閑時,第一個發送顯性位的節點獲得總線訪問權。
2.仲裁段(Arbitration Field)
這個字段決定了報文的優先級,并在多個節點同時發送時解決沖突(仲裁)。
它由兩部分組成:
- 標識符(Identifier):
– 長度:11 bits
– 作用:標識報文的含義和優先級。ID值越小,優先級越高(因為顯性位0優先)。例如,ID為0x000的報文優先級最高,ID為0x7FF的優先級最低。接收節點根據ID來決定是否接收該報文。 - 遠程傳輸請求位(RTR-Remote Transmission Request):
– 長度:1 bit
– 作用:區分是 數據幀 還是 遠程幀。
— 數據幀(Data Frame):RTR = 顯性位(0)。表示該幀帶有數據。
— 遠程幀(Remote Frame):RTR = 隱性位(1)。用于向其他節點請求發送具有相同ID的數據幀。遠程幀沒有數據段。
3.控制段(Control Field)
這個字段提供了關于數據長度的信息。
它由三部分組成:
-
標識符擴展位(IDE-Identifier Extension)
– 長度:1 bit
– 作用:區分標準幀和擴展幀。
— 標準幀:IDE = 顯性位(0)。
— 擴展幀:IDE = 隱性位(1)。(擴展幀的仲裁段結構不同) -
保留位(r0):
– 長度:1 bit
– 作用:保留位,必須發送顯性位(0),但接收器可以接收顯性或隱性位。 -
數據長度碼(DLC-Data Length Code):
– 長度:4 bit
– 作用:指示數據段中包含的字節數。取值范圍從0到8。DLC值大于8的情況在CAN FD中定義,經典CAN中無效。
4.數據段(Data Field)
- 長度:0-8 bytes(由DLC決定)
- 作用:包含實際要傳輸的數據內容。這是報文的有效載荷。CAN協議允許靈活的數據長度,非常適合傳輸控制命令、傳感器讀數等短小精悍的信息。
5.CRC段(CRC Field)
這個字段用于檢測傳輸錯誤。
它由兩部分組成:
-
CRC序列(CRC Sequence)
– 長度:15 bits
– 作用:循環冗余校驗值。由發送器根據幀起始、仲裁段、控制段和數據段的內容計算得出。 -
CRC界定符(CRC Dilimiter)
– 長度:1 bit
– 值:隱性位(1)
– 作用:作為一個固定的分隔符,標志著CRC序列的結束。
6.應答段(ACK Field)
這個字段用于接收節點確認是否接收到報文。
它由兩部分組成:
-
應答間隙(ACK Slot):
– 長度:1 bit
– 發送器行為:發送一個隱性位(1)。
– 接收器行為:任何正確接收到報文(通過CRC校驗)的接收節點,都會在ACK Slot時間段內發送一個**顯性位(0)**來覆蓋它。 -
應答界定符(ACK Dilimiter):
– 長度:1 bit
– 值:隱性位(1)
– 作用:標志著應答段的結束。它必須為隱性位。
ACK段的工作方式:發送器發送隱性位(1),如果至少有一個接收器正確接收了幀,它就會用顯性位(0)覆蓋這個位。因此,發送器如果在ACK Slot讀到隱性位(1),就知道沒有節點成功接收,會觸發錯誤并重發。
7.結束段(EOF-End Of Frame)
– 長度:7 bits
– 值:全部為隱性位(1)
– 作用:明確標志該幀的傳輸結束。
8.幀間間隔(IFS-Inter Frame Space)
雖然嚴格來說不屬于幀的一部分,但它是幀與幀之間必需的間隔。
- 長度:3 bits(或更多,具體由控制器實現決定)
- 作用:在幀結束和下一幀開始(或總線空閑)之間提供一個最小間隔,讓控制器內部有足夠的時間處理剛接收到的幀。
總結與特點
- 非破壞性仲裁:基于標識符(ID)的優先級仲裁機制。優先級高的報文繼續發送,優先級低的自動退出發送并在總線空閑時重試,沒有任何數據損失或丟失。
- 高可靠性:通過CRC校驗、應答位(ACK)和強大的錯誤檢測與信令機制,保證了數據傳輸的極高可靠性。
- 廣播與過濾:報文被廣播到所有節點,每個節點通過標識符過濾來決定是否接收和處理該報文。
- 短小高效:數據長度最高為8字節,開銷小,非常適合高實時性要求的控制系統。
具體例子
下面,我將通過一個具體的例子來詳細說明標準CAN幀的每一部分。
場景設定
假設我們有一個簡單的汽車網絡,里面有兩個節點:
1.發動機控制單元(ECU_Engine):負責報告發動機轉速。
2.儀表盤單元(ECU_Dashboard):負責接收轉速并顯示在轉速表上。
ECU_Engine需要沒秒發送100次發動機轉速數據。我們假設當前發動機轉速為 3000 RPM。
步驟1:組幀前的準備
1.報文標識符(ID):我們需要為轉速報文分配一個唯一的ID。假設我們分配 ID = 0x123(十六進制)。這個ID決定了報文的優先級。0x123
是一個中等偏高的優先級(因為數值較小)。
2.數據:轉速數據為3000。我們需要用2個字節(16位)來表示它。假設我們使用大端模式(Big-endian)(即高位字節在前):
- 3000的十六進制是
0x0BB8
。 - 因此,數據段的兩個字節為:
– Byte 0 =0x0B
(高字節)
– Byte 1 =0xB8
(低字節)
3.數據長度:我們有2個字節的數據,所以數據長度碼(DLC)為2
。
步驟2:構建標準數據幀
現在,我們來逐字段構建這個轉速數據幀。
字段 | 值(二進制) | 值(十六進制) | 說明 |
---|---|---|---|
1.幀起始(SOF) | 0 | - | 一個顯性位(0),標志開始。 |
2.仲裁段 | |||
標識符(11位) | 001 0010 0011 | 0x123 | 這是報文的ID。注意最高7位是0x09 (0010010 ),最低4位是0x3 (0011),合起來是0x123 。 |
RTR位 | 0 | - | 顯性位(0),表面這是一個數據幀 |
3.控制段 | |||
IDE位 | 0 | - | 顯性位(0),表面這是標準幀(11位ID)。 |
保留位r0 | 0 | - | 必須發送顯性位(0)。 |
DLC(4位) | 0100 | 0x2 | 數據長度為 2個字節。 |
4.數據段(2字節) | |||
數據字節0 | 0000 1011 | 0x0B | 轉速數據的高字節(3000的高位部分)。 |
數據字節1 | 1011 1000 | 0xB8 | 轉速數據的低字節(3000的低位部分)。 |
5.CRC段 | |||
CRC序列(15位) | CRC算法(計算得出) | e.g., 0x7FAC | 發送器根據前面所有位計算出的校驗值。假設這里是 0x7FAC |
CRC界定符 | 1 | - | 隱性位(1),固定格式。 |
6.應答段(ACK) | |||
ACK間隙 | 1 →\to→ 0 | - | 發送器發送隱性位(1),但被接收器用顯性位(0)覆蓋。 |
ACK界定符 | 1 | - | 隱性位(1),固定格式。 |
7.結束段(EOF) | 1111111 | - | 7個連續的隱性位(1),標志幀結束。 |
8.幀間間隔(IFS) | - | - | 總線短暫空閑,為下一幀做準備。 |
步驟3:總線上的傳輸與仲裁過程
1.發送:ECU_Engine開始將上述比特流逐位放到CAN總線上,從SOF開始。
2.仲裁(假設此時有另一個節點要發送低優先級消息):
-
在發送仲裁段(ID+RTR)時,ECU_Engine也在監聽總線。
-
它發送ID
0x123
(00100100011
)。 -
如果另一個節點同時發送一個ID為
0x124
(00100100100
)的報文,仲裁會發生:
– 前8位(00100100
)兩者完全相同,總線狀態也一致,沒有勝負。
– 比較第9位:ECU_Engine發0
,另一個節點發0
,還是平手。
– 比較第10位:ECU_Engine發0
,另一個節點發1
。
– 顯性位(0)優先于隱性位(1)。因此,ECU_Engine贏得仲裁,繼續發送。
– 另一個節點檢測到它發送的是隱性位(1),但讀到的是顯性位(0),意識到自己優先級更低,立即退出發送模式轉為接收模式,等待下次重試。 -
這就是非破壞性仲裁:高優先級報文無延遲地繼續發送,低優先級報文自動退出,沒有任何數據損壞。
步驟4:接收與應答過程
1.接收:總線上所有節點(包括ECU_Dashboard)都接收這個幀。
2.CRC校驗:每個接收節點都用同樣的算法對接收到的數據(SOF,仲裁段,控制段,數據段)進行計算,得到一個CRC值。
3.發送應答(ACK):
- 在ACK Slot時間段,發送器ECU_Engine會釋放總線,發送一個隱性位(1)。
- 所有正確接收到該幀(即CRC校驗通過)的節點(在這個例子中,ECU_Dashboard肯定會的),都會在ACK Slot時間段內**發送一個顯性位(0)**來覆蓋這個隱性位。
4.確認:
- 發送器ECU_Engine在ACK Slot讀總線。如果它讀到了顯性位(0),它就知道至少有一個節點成功接收了它的報文,于是認為發送成功。
- 如果它讀到的仍然是隱性位(1),就意味著沒有一個節點成功接收,這將出發錯誤計數器,ECU_Engine會稍后自動重發該報文。
步驟5數據處理
ECU_Dashboard成功接收幀后:
1.通過ID0x123
識別出這是發動機轉速報文。
2.根據DLC2
知道數據段有2個字節。
3.從數據段提出兩個字節0x0B
和0xB8
。
4.將它們組合成0x0BB8
,轉換為十進制數字 3000 。
5.最后,驅動轉速表指針指向3000 RPM的位置。