CAN總線簡明易懂教程

先看看工作原理


當 CAN 總線上的一個節點(站)發送數據時,它以報文的形式廣播給網絡中所有節點,對每個節點來說,無論數據是否是發給自己的,都對其接收。


每組報文開頭的11 位字符為標識符,定義了報文的優先級,這種報文格式成為面向內容的編制方案。同一系統中標識符是唯一的,不可能有兩個站發送具有相同標識符的報文,當幾個站同時競爭總線讀取時,這種配置十分重要。


大體的工作原理我們搞清了,但是根本的協議我們還要花一番功夫。下面介紹一個重要的名詞,“顯性”和“隱性”:


在我看到的很多文章裡,有很多顯性和隱性的地方,為此我頭痛不已,最終我把它們徹底弄明白了。


首先 CAN 數據總線有兩條導線,一條是黃色的,一條是綠色的------分別是CAN_High 線和CAN_Low 線,當靜止狀態時,這兩條導線上的電平一樣,這個電平稱為靜電平,大約為2.5 伏。


這個靜電平狀態就是隱形狀態,也稱隱性電平,也就是沒有任何干擾的時候的狀態稱為隱性狀態。當有信號修改時,CAN_High 線上的電壓值變高了,一般來說會升高至少1V;而CAN_Low 線上的電壓值會降低一個同樣值,也是1v。


那麼這時候,CAN_High 就是 2.5v+1v=3.5v,它就處於激活狀態了。而CAN_Low 降為2.5v-1v=1.5v。可以看看這個圖


CAN總線簡明易懂教程


由此我們得到


在隱性狀態下,CAN_High 線與CAN_Low 沒有電壓差,這樣我們看到沒有任何變化也就檢測不到信號。但是在顯性狀態時,改值最低為2V,我們就可以利用這種變化才傳輸數據了。所以出現了那些幀,那些幀中的場,那些場中的位,云云。


在總線上通常邏輯1 表示隱性。而0 表示顯性。這些1 啊,0 啊,就可以利用起來為我們傳數據了。利用這種電壓差,我們可以接收信號。


一般來說,控制單元通過收發器連接到 CAN 驅動總線上,這個收發器(顧名思義,可發送,可接收)內有一個接收器,該接收器是安裝在接收一側的差動信號放大器。然後,這個放大器很自然地就放大了CAN_High 和CAN_Low 線的電平差,然後傳到接收區。如下圖


CAN總線簡明易懂教程


由上圖可知,當有電壓差,差動信號放大器放大傳輸,將相應的數據位轉化為0。


下面我們進入重點難點-----報文


所謂報文,就是CAN 總線上要傳輸的數據報,為了安全,我們要給我們傳輸的數據報編碼定一下協議,這樣才能不容易出錯,所以出現了很多的幀,以及仲裁啊,CRC 效驗。這些都是難點。


識別符的概念


識別符顧名思義,就是為了區分不同報文的可以鑑別的好多字符位。有標準的,和擴展的。標準的是11 位,擴展的是29 位。他有一個功能就是可以提供優先級,也就是決定哪個報文優先被傳輸,報文標識符的值越小,報文具有越高的優先權。


CAN 的報文格式有兩種,不同之處其實就是識別符長度不同,具有11 位識別符的幀稱為標準幀,而還有29 位識別符的幀為擴展幀,CAN 報文有以下4 個不同的幀類型。分別是:


(1) 數據幀:數據幀將數據從發送器傳輸到接收器;

(2) 遠程幀:總線節點發出遠程幀,請求發送具有同一標識符的數據幀;

(3) 錯誤幀:任何節點檢測到總線錯誤就發出錯誤幀;

(4) 過載幀:過載幀用已在先行的後續的數據幀(或遠程幀)之間提供一附加的延時。


我們先研究數據幀吧。


一,數據幀由 7 個不同位場組成

(幀起始、仲裁場、控制場、數據場、CRC場、應答場、幀結尾)。


這裡的位場,就是不同位的組合,這名字起的很爛,讓人看了感覺很抽象。我們來看看這些個不同的位場吧。一開始是一位幀起始,也叫SOF。它用顯性位表示,也就是0;它告訴我們,兩個線上有電壓差了,也就是有數據了。


這個幀起始看起來只有一位,其實不簡單了。為了讓所有的分站都同步於發送報文的發送站,好接收數據,有很多要考慮的地方。


CAN總線簡明易懂教程

報文的數據幀結構


然後下一個場是仲裁場。這個仲裁很抽象,其實在這裡就是為了解決一個問題。如果2 個或2 個以上的單元同時開始傳送報文,那麼就會有總線訪問衝突,那麼仲裁機制就是用來根據標識符優先級來一個一個的去掉低級別的數據。我們可以詳細的描述這場生動的爭搶總線的戰鬥。


當總線處於空閒狀態時呈隱性電平,此時任何節點都可以向總線發送顯性電平作為幀的開始。2 個或2 個以上的節點同時發送開始爭搶總線,但是總線只能被一個人搶走。這時候到底怎麼決定誰留下,誰滾蛋呢。我們開始思索,我們以前定義了標識符,標識符有優先級,它越小,它優先級越高。那麼怎麼實現的呢。看下面圖:


首先搞明白兩點,

一、下圖中, 低波形代表0(顯性),高波形代表1(隱性);

二、當隱性碰到顯性,就變為顯性。


CAN總線簡明易懂教程


如圖所示,節點 A 和節點B 的標識符的第10、9、8 位電平相同,因此兩個節點偵聽到的信息和它們發出的信息相同。第7位節點B發出一個“1”,但從節點上接收到的消息卻是“0”。


為什麼呢,因為A 節點同時發出顯性位,讓總線也變成顯性了,也就是0。節點B 會退出發送處於單純監聽方式而不發送數據;節點A 成功發送仲裁位從而獲得總線的控制權,繼而發送全部消息。


總線中的信號持續跟蹤最後獲得總線控制權發出的報文,本例中節點A的報文將被跟蹤。這種非破壞性位仲裁方法的優點在於,在網絡最終確定哪個節點被傳送前,報文的起始部分已經在網絡中傳輸了,因此具有高優先級的節點的數據傳輸沒有任何延時。


在獲得總線控制權的節點發送數據過程中,其他節點成為報文的接收節點,並且不會在總線再次空閒之前發送報文,在這逐位的比較中,最終節點B 因為第七位的偏差丟掉了總線。從此單純監聽,江山就拱手讓給了節點A 了。這就是仲裁機制。


上面我們說過,報文有兩種格式,標準和擴展。這裡,不同的格式仲裁場是不一樣的。標準格式下,仲裁場由11 位識別符和RTR 位組成。


但在擴展格式裡,包括29 位識別符、SRR 位、IDE 位、RTR 位。


RTR 位,Remote Tranmission Request BIT 全稱為遠程發送請求位。它在數據幀裡必須為顯性0 ,但在遠程幀裡為隱性1。


我暈,為什麼這麼搞呢,不急,先留著這個問題。


SRR 位,替代遠程請求位,SRR 是一隱性位,也就是1,它在擴展格式的標準幀RTR 位位置,那麼標準幀怪不得優先於擴展幀了,因為在傳輸完11 位標識符之後(擴展幀的後18 位在最後發送,先發送11 位標識符),輪到標準幀的RTR 位和擴展幀的SRR 位了。


這時候,標準幀的RTR 為顯性,而擴展幀SRR 為隱性,這樣,總線自然就被標準幀佔據。


同時上面那個問題,也一目瞭然了,CAN 總線協議設計者,肯定是設計了數據幀優先於遠程幀。所以IDE(Identifier Extension Bit),全稱識別符擴展位,它屬於擴展格式的仲裁場。


對於擴展格式,IDE位屬於仲裁場;對於標準格式,IDE位屬於控制場。標準格式的IDE位為“顯性”,而擴展格式的IDE位為“隱性”。


CAN總線簡明易懂教程

標準格式中的數據幀


CAN總線簡明易懂教程

拓展格式中的數據幀

控制場


控制場由6個位組成,標準格式和擴展格式的控制場格式不同。標準格式裡的幀包括數據長度代碼、IDE位(為顯性位)及保留位r0。擴展格式裡的幀包括數據長度代碼和兩個保留位:r1和r0。其保留位必須發送為顯性,但是接收器認可“顯性”和“隱性”位的任何組合。其結構如圖所示:


CAN總線簡明易懂教程

控制場結構


數據長度代碼(標準格式以及擴展格式)DLC,如下表所示


CAN總線簡明易懂教程


數據幀長度代碼DLC


數據長度代碼指示了數據場裡的字節數量。其中:d—“顯性”, r—“隱性”,數據幀允許的數據字節數為{0,1,...,7,8}。其他的數值不允許使用。


數據場


數據場由數據幀裡的發送數據組成。它可以為0~8個字節,每字節包含了8個位,首先發送最高有效位(MSB)。


循環冗餘碼CRC場是數據通信領域中最常用的一種差錯校驗碼,其特徵是信息字段和校驗字段的長度可以任意選定。


CRC場包括CRC序列(CRC Sequence),其後是CRC界定符(CRC Delimiter),結構如圖:


CAN總線簡明易懂教程


生成 CRC 碼的基本原理:


任意一個由二進制位串組成的代碼都可以和一個係數僅為‘0’和‘1’取值的多項式一一對應。例如:代碼1010111 對應的多項式為x6+x4+x2+x+1,而多項式為x5+x3+x2+x+1 對應的代碼101111。


參考一下下面的例題,自已再領悟一下吧!已知信息位為1101,生成多項式G(x)= x3+x+1,求CRC 碼。


要傳輸的信息序列為1101,在末尾添加所給多項式的最高次階個0,如本題為x^3,則添加3個0,變為:1101000;


由多項式G(X)=X3+X+1,得其階數為1的二進制編碼為:1011;1101000對1011進行模二除法,所得到的餘數即為校驗碼,把校驗碼添加在原數據尾部即為所求的編碼,則實際發送的數據序列為1101001。校驗碼計算過程如圖所示:


CAN總線簡明易懂教程

模二除法


應答場(ACK Field)


應答場長度為2個位,包含應答間隙(ACK Slot)和應答界定符(ACK Delimiter),如圖所示。在ACK場(應答場)裡,發送節點發送兩個“隱性”位。


當接收器正確地接收到有效的報文,接收器就會在應答間隙(ACK Slot)期間向發送器發送一“顯性”位以示應答。


CAN總線簡明易懂教程

幀結尾


每一個數據幀和遠程幀均由一標誌序列界定。這個標誌序列由7個“隱性”位組成。


二、遠程幀


通過發送遠程幀,總線的節點發出遠程幀,請求以前發送給它數據幀的節點再發送一遍。具體發送哪個數據幀,由遠程幀的標識符決定。


與數據幀類似,遠程幀也有標準格式和擴展格式,而且都由6個不同的位場組成:幀起始、仲裁場、控制場、CRC場、應答場、幀結尾。


與數據幀相反,遠程幀的RTR位是“隱性”的。它沒有數據場,數據長度代碼DLC的數值是不受制約的(可以標註為容許範圍0~8裡的任何數值),此數值是相應於數據幀的數據長度代碼。遠程幀結構如圖所示:


CAN總線簡明易懂教程

遠程幀結構


三、錯誤幀


錯誤幀由兩個不同的場組成,第一個場是不同節點提供的錯誤標誌(Error Flag)的疊加,第二個場是錯誤界定符。


為了能正確地終止錯誤幀,“錯誤認可”的節點要求總線至少有長度為3個位時間的總線空閒。因此,總線的載荷不應為100%。錯誤幀結構如圖:


CAN總線簡明易懂教程

錯誤幀結構(圖中統一起見出錯幀改為錯誤幀)


(1) 錯誤標誌,有兩種形式的錯誤標誌:激活錯誤標誌 和 認可錯誤標誌

“激活錯誤”標誌由6個連續的“顯性”位組成;“認可錯誤”標誌由6個連續的“隱性”的位組成,除非被其他節點的“顯性”位重寫。


(2) 錯誤界定符,錯誤界定符包括8個“隱性”的位。


錯誤標誌傳送了以後,每一個節點就發送一個“隱性”的位,並一直監視總線直到檢測出一個“隱性”的位為止,然後就開始發送其餘7個“隱性”位。


四、過載幀


過載幀(Overload Frame)包括兩個位場:過載標誌 和 過載界定符,其結構如圖:


CAN總線簡明易懂教程

過載幀結構圖


有三種過載的情況會引發過載標誌的傳送:接收器的內部情況,需要延遲下一個數據幀和遠程幀。


在間歇(Intermission)的第1和第2字節檢測到一個“顯性”位。這裡有個間歇的概念。我們可以講講。間歇屬於幀間空間的一部分。它包含三個隱性位。間歇期間,所有的站不允許傳送數據幀或遠程幀。它唯一要做的就是標示一個過載條件。


如果CAN節點在錯誤界定符或過載界定符的第8位(最後一位)採樣到一個顯性位,節點會發送一個過載幀。該幀不是錯誤幀,錯誤計數器不會增加。


(1)過載標誌(Overload Flag)

過載標誌由6個“顯性”的位組成。過載標誌的所有形式和“激活錯誤”標誌的一樣。


(2)過載界定符(Overload Delimiter)

過載界定符包括8個“隱性”的位。


五、幀間空間


數據幀(或遠程幀)與先行幀的隔離是通過幀間空間實現的,無論此先行幀類型如何(數據幀、遠程幀、錯誤幀、過載幀)。


幀間空間包括間歇、總線空閒的位場。如果“錯誤認可”的節點已作為前一報文的發送器,則其幀間空間除了間歇、總線空閒外,還包括稱作“掛起傳送”(暫停發送)(Suspend Transmission)的位場。


對於不是“錯誤認可”的節點,或作為前一報文的接收器的節點,其幀間空間如圖:


CAN總線簡明易懂教程

非 “錯誤認可”幀間空間


對於作為前一報文發送器的“錯誤認可”的節點,其幀間空間如圖:


CAN總線簡明易懂教程

“錯誤激活”幀間空間


(1)總線空閒(Bus Idle)

總線空閒的時間是任意的。只要總線被認定為空閒,任何等待發送報文的節點就會訪問總線。在發送其他報文期間,有報文被掛起,對於這樣的報文,其傳送起始於間歇之後的第一個位。總線上檢測到的“顯性”的位可被解釋為幀的起始。


(2)掛起傳送(Suspend Transmission)

“錯誤認可”的節點發送報文後,節點就在下一報文開始傳送之前或總線空閒之前發出8個“隱性”的位跟隨在間歇的後面。如果與此同時另一節點開始發送報文(由另一節點引起),則此節點就作為這個報文的接收器。


最後用腦圖總結:


CAN總線簡明易懂教程


再來幾張實物圖:


CAN總線簡明易懂教程

CAN總線接收芯片


CAN總線簡明易懂教程

CAN總線控制器芯片


CAN總線簡明易懂教程

標準數據幀波形捕獲


CAN總線簡明易懂教程

擴展數據幀波形捕獲


分享到:


相關文章: