CAN總線是一種常用的總線,對于剛開始接觸CAN總線的,面對著各式各樣的資料,可能不知道從何看起,今天科普一下CAN總線的基礎(chǔ)知識。CAN2.0協(xié)議分為A版本和B版本,A版本協(xié)議為11位標識符(標準幀),B版本在兼容11位ID標識符的同時,向上擴展到29位ID標識符。
CAN總線的物理電平
對 CAN 總線的協(xié)議了解之前,先介紹一下 CAN總線的電平,CAN總線的基本狀態(tài)有兩種,分別為“顯性”和“隱性”,也就是“邏輯 0”和“邏輯 1”,如圖 1:
圖中兩個 CAN 總線節(jié)點分別接在 CAN 總線上,兩個終端為什么要接兩個 120Ω的終端電阻?
首先解釋一下“終端電阻”這個名詞,終端電阻是一種信號在傳輸過程中遇到的阻礙,高頻信號傳輸時,信號波長相對傳輸線較短,信號在傳輸線終端會形成反射波,干擾原信號,所以需要在傳輸線末端加終端電阻,使信號到達傳輸線末端后不反射。對于低頻信號則不用。在長線信號傳輸時,一般為了避免信號的反射和回波,也需要在接收端接入終端匹配電阻。
終端匹配電阻值取決于電纜的阻抗特性,特別注意的是與電纜的長度無關(guān)。RS-485/RS-422 /CAN 總線一般采用雙絞線(屏蔽或非屏蔽)連接,終端電阻一般介于100至140Ω之間,典型值為120Ω。在實際配置時,在電纜的兩個終端節(jié)點上,即最近端和最遠端,各接入一個終端電阻,而處于中間部分的節(jié)點則不能接入終端電阻,否則將導(dǎo)致通訊出錯。
現(xiàn)在繼續(xù)介紹 CAN 總線的邏輯,CAN 總線傳輸數(shù)據(jù)時,依靠的是差分電平,因為 CAN 總線是雙絞線,所以在沒有數(shù)據(jù)傳輸時,兩條線的電壓相同,均為2.5V,差值為 0,所以為“隱形”,若是有數(shù)據(jù)傳輸時,兩條線就會出現(xiàn)電壓不通的情況,CAN_H 為 3.5V、CAN_L 為 1.5V,電壓差為 2V,所以為“顯性”。
現(xiàn)在用兩個等式來對 CAN 的電平做一個總結(jié),那就是:
CAN 總線為隱性 = 無電壓差 = 邏輯 1
CAN 總線為顯性 = 有電壓差 = 邏輯 0
CAN報文幀詳解
在了解 CAN 硬件之后,知道了邏輯“0”和邏輯“1”,CAN 報文幀就是由這些0和1組成。 由圖可以看出,CAN-bus 的通信幀共分為五種幀:?數(shù)據(jù)幀、遠程幀、錯誤幀、過載幀和幀間隔?,數(shù)據(jù)幀又有標準幀和擴展幀兩種。
數(shù)據(jù)幀和遙控幀
在 CAN 協(xié)議中,數(shù)據(jù)幀和遙控幀有著諸多相同之處,將數(shù)據(jù)幀和遙控幀放在一起來講。 數(shù)據(jù)幀是指包含了要傳輸?shù)臄?shù)據(jù)的幀,作用是承載發(fā)送節(jié)點要傳遞給接收節(jié)點的數(shù)據(jù)。
遙控幀的作用:?請求其它節(jié)點發(fā)出與本遙控幀具有相同 ID 號的數(shù)據(jù)幀。 發(fā)起方發(fā)起特定ID的遙控幀,并且只發(fā)送ID部分,那么與其 ID相符的終端設(shè)備就有義務(wù)在后半段的數(shù)據(jù)部分接管總線控制權(quán)并發(fā)送自己的數(shù)據(jù)。
例如中控機需要定時獲取某個節(jié)點的數(shù)據(jù)(例如轉(zhuǎn)速計的實時轉(zhuǎn)速、油量計的實時油量等),可以向總線發(fā)送遠程幀; 相應(yīng)節(jié)點在接收判斷幀 ID與自己相符、并且是遠程幀的情況下,就可以將自己的實時數(shù)據(jù)發(fā)送到總線上; 這樣中控機就獲取到了相關(guān)節(jié)點的實時數(shù)據(jù)。
遠程幀最大的好處就是只需要一幀的時間就能完成一次雙向交互。
兩種幀格式由幀起始、仲裁幀、控制端、數(shù)據(jù)段、CPC 段、ACK 段、幀結(jié)束, 不同的段有不同的用途。
起始段
幀的最開始的一位是幀起始,也叫 SOF(Start Of Frame),SOF 恒為顯性位,即邏輯0。 幀起始表示CAN_H和CAN_L上有了電位差,也就是說,一旦總線上有了 SOF 就表示總線上開始有報文了。
仲裁段
CAN 總線有一個特點,就是所有節(jié)點均可以獲得總線的控制權(quán)并且向 CAN 總線發(fā)送數(shù)據(jù),當同時有 2 個或 2 個以上的設(shè)備要求發(fā)送數(shù)據(jù)時,就會產(chǎn)生總線沖突,這時就需要判斷一個先后順序,而仲裁段就是判斷先后順序的裁判員,仲裁段會對 CAN 數(shù)據(jù)進行比較,ID 碼值越小的數(shù)據(jù)越具有優(yōu)先權(quán),從而使具有高優(yōu)先級的數(shù)據(jù)不受任何損壞地傳輸。
仲裁段是如何仲裁的? 各節(jié)點在向總線發(fā)送電平的同時,也對總線上的電平讀取,并與自身發(fā)送的電平進行比較,如果電平相同繼續(xù)發(fā)送下一位,不同則停止發(fā)送退出總線競爭。 剩余的節(jié)點繼續(xù)上述過程,直到總線上只剩下1個節(jié)點發(fā)送的電平,總線競爭結(jié)束,優(yōu)先級高的節(jié)點獲得總線的控制權(quán)。
假設(shè) CAN 總線上有兩個節(jié)點,節(jié)點A和節(jié)點 B,節(jié)點A 的 ID為 10101000000,節(jié)點 B 的ID為 101100000,當節(jié)點 A 和節(jié)點 B 同時向CAN 總線發(fā)送數(shù)據(jù)時,如下圖,當發(fā)送到 ID7 時,節(jié)點 A 仲裁成功,從而獲得 CAN 總線的控制權(quán),繼而發(fā)送全部消息。
總線中的信號持續(xù)跟蹤最后獲得總線控制權(quán)發(fā)出的報文,在這里值得注意的是,CAN 總線的這種仲裁方式優(yōu)點在于,無論是總線的控制權(quán)在哪個節(jié)點,CAN 總線傳輸?shù)膱笪囊呀?jīng)在總線上傳輸了。
因此,CAN 總線具有高優(yōu)先級的節(jié)點的數(shù)據(jù)在傳輸時,沒有任何延遲,在獲得總線控制權(quán)的節(jié)點發(fā)送數(shù)據(jù)過程中,其他節(jié)點成為報文的接收節(jié)點,并且不會在總線再次空閑之前發(fā)送報文。
仲裁段是用來判定一幀報文優(yōu)先級的依據(jù)?,仲裁段中的 ID 號也是實現(xiàn)報文過濾機制的基礎(chǔ)。 那么不同幀的優(yōu)先級是怎么體現(xiàn)的呢?
RTR 位:?Tranmission Request Bit (遠程發(fā)送請求位),RTR 用來區(qū)分該幀是數(shù)據(jù)幀還是遠程幀。 當 RTR為邏輯 0 時,代表該幀為數(shù)據(jù)幀; 當 RTR 為邏輯 1 時,代表該幀為遠程幀。
由圖可以看出,當四種傳輸幀時,由于標準數(shù)據(jù)幀和擴展數(shù)據(jù)幀的RTR 都為 0,可以看出數(shù)據(jù)幀的優(yōu)先級大于遠程幀的優(yōu)先級。 RTR 的作用是在前 11 位 ID 號相同的情況下,保證數(shù)據(jù)幀優(yōu)先級高于遠程幀。
SRR 位:?Substitutes for Remote Requests Bit(替代遠程請求位)
在擴展幀(數(shù)據(jù)幀或遙控幀)中,SRR 恒為隱性位 1,并且可以發(fā)現(xiàn),擴展幀的隱性 SRR 位正好對應(yīng)標準數(shù)據(jù)幀的顯性 RTR 位,可以看出標準幀的優(yōu)先級高于擴展幀。SRR 位的作用,在前 11 位 ID 號相同的情況下,標準數(shù)據(jù)幀的優(yōu)先級高于擴展數(shù)據(jù)幀。
IDE 位:?Identifier Extension Bit(標識符擴展位),IDE 用來區(qū)分該幀是標準幀幀還是擴展幀。當 IDE 為邏輯 0 時,代表該幀為標準幀;當 IDE 為邏輯 1 時,代表該幀為擴展幀。擴展幀 IDE 位和標準幀 IDE 位位置對應(yīng),可以看出,標準遙控幀的優(yōu)先級一定高于擴展遙控幀。IDE 位的作用,在前 11 位相同的情況下,標準數(shù)據(jù)幀的優(yōu)先級高于擴展數(shù)據(jù)幀。
在 ID 號前 11 位相同的情況下:
RTR :保證數(shù)據(jù)幀優(yōu)先級高于遠程幀;
SRR :保證標準數(shù)據(jù)幀的優(yōu)先級高于擴展數(shù)據(jù)幀。
IDE :保證標準遙控幀的優(yōu)先級高于擴展遠程幀。
控制段
控制段由6個位組成,標準格式和擴展格式的控制場格式不同。
標準格式里的幀包括:數(shù)據(jù)長度代碼、IDE 位(為顯性位)及保留位 RB0。
擴展格式里的幀包括:數(shù)據(jù)長度代碼、兩個保留位 RB0 和 RB1。其保留位必須發(fā)送為顯性,但是接收器認可“顯性”和“隱性”位的任何組合,其結(jié)構(gòu)如圖所示:
數(shù)據(jù)幀長度代碼(DLC),指示了數(shù)據(jù)場里的字節(jié)數(shù)量。其中:d—“顯性”, r—“隱性”, 數(shù)據(jù)幀允許的數(shù)據(jù)字節(jié)數(shù)為{0,1,...,7,8}。其他的數(shù)值不允許使用。
數(shù)據(jù)段
數(shù)據(jù)段由數(shù)據(jù)幀里的發(fā)送數(shù)據(jù)組成。它可以為 0~8 個字節(jié),每字節(jié)包含了 8 個位,首先發(fā)送最高有效位(MSB)。
CRC校驗段
CRC 包含 CRC 校驗序列和 CRC 界定符(恒為隱形,即邏輯 1),通過多項式生成 CRC 值,比較發(fā)送節(jié)點與接受節(jié)點 CRC 是否一致,來確保幀的有效性,計算范圍包括發(fā)送節(jié)點【幀起始、仲裁場、控制場、數(shù)據(jù)場】是否與接收節(jié)點【幀起始、仲裁場、控制場、數(shù)據(jù)場】是否一致。
傳統(tǒng) CAN 使用的是 CRC15 的算法,這個通過 CAN 的數(shù)據(jù)結(jié)構(gòu)也可以看出,CRC段的長度就是 15 位。CAN FD 之所以有兩種是因為 CAN FD 的數(shù)據(jù)長度是可變的, 針對不同的數(shù)據(jù)長度使用的方法不同,低于 16 字節(jié)的使用的是 CRC17,高于 16 字節(jié)的使用的是 CRC21。
ACK段
ACK段包含 ACK 槽和 ACK 界定符兩個位。
發(fā)送節(jié)點在 ACK 段發(fā)送兩個隱性位,即發(fā)送方發(fā)出的報文中 ACK 槽為隱性 1;接收節(jié)點在接收到正確的報文之后會在 ACK 槽發(fā)送顯性位 0,通知發(fā)送節(jié)點正常接收結(jié)束。所謂接收到正確的報文指的是接收到的報文沒有填充錯誤、格式錯誤、CRC 錯誤。
以標準數(shù)據(jù)幀為例來分析 ACK 段的工作方式,Node_A 為發(fā)送節(jié)點, Node_B 為接收節(jié)點。Node_A 在 ACK 段發(fā)送兩個隱性位 1。Node_B 正確接收到這一報文后,在 ACK 段的 ACK 槽中填充了一個顯性位 0。注意,這個時候 Node_A 回讀到的總線上的額電平為顯性 0,于是這個時候,Node_A 就知道自己發(fā)出去的報文至少有一個節(jié)點正確接收了。
結(jié)束段(EOF)
每一個數(shù)據(jù)幀或遠程幀均由 7 個連續(xù)的隱性位 1 組成。幀結(jié)束強制不遵守位填充特性,表達出明顯的結(jié)束標識。這樣接收節(jié)點可以正確檢測到一個幀的傳輸結(jié)束。
我們在《詳解常用的CAN總線(上):報文幀》一文中詳細了解了CAN總線的報文幀,今天一起來看看常遇到的錯誤幀。
錯誤幀種類
錯誤幀種類分為5種,分別是:位發(fā)送錯誤、ACK錯誤、位填充錯誤、CRC錯誤、格式錯誤。
位發(fā)送錯誤
節(jié)點將自己發(fā)送到總線上的電平與同時從總線上回讀到的電平進行比較,如果發(fā)現(xiàn)二者不一致,那么這個節(jié)點就會檢測出一個位錯誤。
實際上所謂“發(fā)出的電平與從總線上回讀的電平不一致”,指的就是節(jié)點向總線發(fā)出隱性位,卻從總線上回讀到顯性位或者節(jié)點向總線發(fā)出顯性位,卻從總線上回讀到隱性位這兩種情況。
ACK錯誤
ACK在ACK段中講解過,按照CAN協(xié)議的規(guī)定,發(fā)送節(jié)點Node_A在一幀報文(數(shù)據(jù)幀或者遙控幀)發(fā)出之后,如果接收節(jié)點Node_B成功接收了該幀報文,那么接收節(jié)點Node_B就要在該幀報文ACK槽對應(yīng)的時間段內(nèi)向總線上發(fā)送一個顯性位來應(yīng)答發(fā)送節(jié)點Node_A。
這樣發(fā)送節(jié)點Node_A就會在ACK槽時間段內(nèi)從總線上回讀到一個顯性位。因此:當發(fā)送節(jié)點Node_A在ACK槽時間段內(nèi)沒有回讀到顯性位,那么發(fā)送節(jié)點Node_A就會檢測到一個ACK應(yīng)答錯誤。這表示沒有一個節(jié)點成功接收該幀報文,此時CAN總線認為是ACK應(yīng)答錯誤
位填充錯誤
幀起始到CRC校驗之前的物理上電平不允許有6個連續(xù)的相同電平,發(fā)送器只要檢測到位流中有5個連續(xù)相同邏輯的位,便會自動在下一位插入一個相反的電平。
從幀起始到CRC之間,接收節(jié)點檢測到有6個連續(xù)相同的位電平時,也就是違反5位相同位插入1位相反位的“位填充”原則;因為ACK域和幀結(jié)束域電平固定,也無需填充;幀起始、仲裁域、控制域、數(shù)據(jù)域以及CRC校驗和域,均通過位填充方法編碼。
位填充是指:無論何時,發(fā)送器只要檢測到位流中有5個連續(xù)相同邏輯的位,便會自動在位流中插入一個補碼位。舉例來說,如果連續(xù)5個顯性位,則在5個顯性位之后自動插入1個隱性位,接收器會自動刪除這個插入的填充位。
數(shù)據(jù)幀或遠程幀的剩余位域(CRC界定符、應(yīng)答域和幀結(jié)尾域)形式固定,不填充;錯誤幀和過載幀也不填充。
那么位填充規(guī)則的作用是什么呢?原因有兩點:
1.CAN網(wǎng)絡(luò)同步需要足夠多的上升沿,這是CAN協(xié)議規(guī)定位填充的目的之一。
2.確保數(shù)據(jù)幀不會被當作錯誤幀(由6個連續(xù)的顯性或隱性位組成)、確保正確識別幀結(jié)束標志(7個連續(xù)隱性位)。
CRC錯誤
發(fā)送端送出的CRC序列由發(fā)送器算出,接收器執(zhí)行同樣的CRC算法,若計算結(jié)果與接收到的CRC序列不符,則認為CRC錯誤。
幀格式錯誤
主動錯誤狀態(tài):?處于主動錯誤狀態(tài)的節(jié)點(可能是接收節(jié)點也可能是發(fā)送節(jié)點)在檢測出錯誤時,發(fā)出主動錯誤標志。
如果發(fā)出主動錯誤幀的節(jié)點是發(fā)送節(jié)點,這個情況下就相當于:剛剛發(fā)送的那一幀報文發(fā)錯了,現(xiàn)在破壞掉它(發(fā)送主動錯誤幀),你們不管收到什么都不算數(shù);
如果發(fā)出主動錯誤幀的節(jié)點是接收節(jié)點,這個情況就相當于:剛剛收報文的時候發(fā)現(xiàn)了錯誤,不管你們有沒有發(fā)現(xiàn)這個錯誤,現(xiàn)在主動站出來告訴大家這個錯誤,并把這一幀報文破壞掉(發(fā)送主動錯誤幀),剛才你們收到的東西不管對錯都不算數(shù)了。
處于主動錯誤狀態(tài),說明這個節(jié)點目前是比較可靠的,出現(xiàn)錯誤的原因可能不是它本身的問題,即剛剛檢測到的錯誤可能不僅僅只有它自己遇到,正是因為這一點,整個總線才相信它報告的錯誤,允許它破壞掉發(fā)送中的報文,也就是將這一次的發(fā)送作廢。
被動錯誤狀態(tài):?錯誤比較多,很可能錯誤是人為導(dǎo)致的,通知其他節(jié)點有錯但是不干擾他們正常收發(fā)數(shù)據(jù),也不要求重發(fā),同時不能連續(xù)發(fā)送了,得再插入8位隱性位的“延遲傳送”段;這樣是為了讓其他正常節(jié)點(處于主動錯誤)優(yōu)先使用總線。
被動錯誤的節(jié)點很可能存在硬件故障,不能讓它拖累整個網(wǎng)絡(luò);
過載幀:接收節(jié)點向總線上其它節(jié)點報告自身接收能力達到極限的,可以這樣理解:接收節(jié)點Node_A接收報文的能力達到極限了,于是Node_A就會發(fā)出過載幀來告訴總線上的其它節(jié)點(包括發(fā)送節(jié)點),接收節(jié)點Node_A已經(jīng)沒有能力處理你們發(fā)來的報文了。
過載幀包括:過載標志和過載界定符兩個部分。
過載標志:連續(xù)6個顯性位。
過載界定符:連續(xù)8個隱性位。
與錯誤幀類似,過載幀中有過載幀重疊部分,且形成過載重疊標志的原因與形成錯誤幀中的錯誤重疊標志的原因是相同的。
那么怎么通俗的理解過載幀呢?
接收節(jié)點Node_A達到接收極限時,就會發(fā)出過載幀到總線上,顯然,過載標志的6個連續(xù)顯性位會屏蔽掉總線上其它節(jié)點的發(fā)送,也就是說這個時候Node_A通過發(fā)送過載幀的方式來破壞其它節(jié)點的發(fā)送,這樣在Node_A發(fā)送過載幀期間,其它節(jié)點就不能成功發(fā)送報文,于是就相當于把其它節(jié)點的發(fā)送推遲了,也就是說Node_A在其發(fā)送過載幀的這段時間得以“休息”。
幀間隔:?用于將數(shù)據(jù)幀或遠程幀和他們之前的幀分離開,但過載幀和錯誤幀前面不會插入幀間隔。也就是說數(shù)據(jù)幀(或者遠程幀)通過插入幀間隔可以將本幀與先行幀(數(shù)據(jù)幀、遠程幀、錯誤幀、過載幀)分隔開來。
審核編輯:湯梓紅
評論