CAN總線是什麼
CAN是一種消息協議,1983年由德國公司Bosch開發。CAN是一種電子設備之間的通訊協議,包含了硬件和軟件兩方面的規定,類似於RS-232、USB、以太網等。他們都只是一種“線”。如果你不想要知道太多,那麼只需要知道儀器用CAN線連在一起,他們之間就可以交換信息了。
CAN主要應用於汽車領域,開發的初衷之一正是統一車輛內各電子設備的通訊,精簡複雜的線束。
稍詳細的內容
CAN總線標準主要在ISO
11898
這個文檔裏,此外還有Bosch的CAN 2.0
。大致上可以分爲“硬件結構是什麼樣”和“如何交換數據”兩部分。
硬件結構是什麼樣
CAN是一種總線,也就是說所有的設備(以下稱爲節點,Node)都接在同一條線上。所有節點可以(儘管不應該)同時操作總線。
CAN是串行的,一般只需要3根線:CAN_H
、CAN_L
、GND
,沒有時鐘。CAN_H
與CAN_L
差分傳送數據,物理上應該雙絞,而GND做線殼。電壓不定,一般來說5V電源時,要表示0
,CAN_H
和CAN_L
都是2.5V;表示1,CAN_H
是3.5V,CAN_L
是1.5V。
CAN線在物理上(不要在意如何)實現了“線與(wired-AND)”的連接方式——任何一個節點輸出0
,總線即爲0
。
如何交換數據
設備之間不分主從,任何設備(節點)都可以操作總線來發送消息,而此時另外的所有節點會收到這條消息。至於收到的消息有沒有用,怎麼用,由節點自行處理。
總線通訊不區分主從節點,就可能會出現衝突:儘管節點只應該在總線空閒時才發送消息,但仍可能會非常巧,有2個或以上的節點同時想要操作總線發送消息。這時需要“仲裁”,到底應該誰來發送。
仲裁利用了“線與”:在任何消息之前附加11位ID,ID決定了消息的優先度,小爲優先度高。任何節點在發送消息ID(寫總線)時也回讀結果,如果發現和自己寫的不一樣,節點就知道還有別的節點在發送數據,並且自己發送的消息優先度更低,於是放棄操作總線。舉個例子:
Node1: 00001000000
Node2: 000011*****
CANBUS: 00001000000
在第6位時,Node2向總線寫0
,而Node2向總線寫1
,總線結果爲1&0=0
。這時Node2退出操作總線,Node1繼續寫總線。
除了ID之外,一條CAN消息的幀結構還有更多內容,有4位DLC來指示數據長度(意味着CAN消息是變長度的);有實際的數據位DATA,最長64位;有15位CRC來保證數據正確;消息後部分有一位ACK,這一位時,發送節點寫1
,接收到的節點寫0
,如果總線爲0
,就表示有至少一個節點接收到了消息。還有其他一些結構,不過它們大多都不必在意。簡單認爲ID之後跟着DLC,之後跟着DATA,最後是ACK就好。
圖片來自wikipedia
擁有了數據
得到了數據之後,這些數據都代表了什麼,是應用層需要處理的事情,CAN標準沒有規定。也就是每位設計,每個系統可以自由發揮。當然也是標準可以參考的,比如CANopen等。
更多內容
更多的內容可以先參考Wikipedia,你會知道:
- CAN線上的
0
被稱爲顯性,而1
被稱爲隱性。 - 上面說的CAN電平其實是“高速CAN”的情況。
- CAN的ID也可以擴展到更多位數。
- CAN消息也分爲幾種,結構有些區別。
- CAN幀還要經過位填充之後纔是實際發送到總線上(用示波器看到)的樣子。這是爲了進行沒有時鐘串行通信的各節點進行時鐘同步。
- CAN信號的比特率大概是
<100MHz
,不過節點工作的頻率應該更快(比如x8=800MHz
)才能較好處理通訊。 - 針對通訊錯誤(比如收到了非法結構的消息),標準規定了一套錯誤處理措施。措施的大意出錯少的節點遇到錯誤時要主動打斷正在傳輸的消息,而出錯太多時要掛起自己以免干擾總線。
接下來可以閱讀網上的一些更詳細的教程,以及ISO
11898-1
、ISO 11898-2
。