當(dāng)前位置:首頁 > 技術(shù)學(xué)院 > 技術(shù)前線
[導(dǎo)讀]CAN通信工作原理個人心得


CAN總線結(jié)構(gòu)示意圖:

說明: 1:CAN收發(fā)器(示意圖中的單元)根據(jù)兩總線CAN_H和CAN_L的電位差來判斷總線電平;

2:實際中CAN_H與CAN_L由雙絞線組成;

3:數(shù)據(jù)傳遞終端的電阻器,是為了避免數(shù)據(jù)傳輸反射回來,使數(shù)據(jù)遭到破壞;

4:電阻阻值為120Ω;

5:CAN通信實際上為單元之間的數(shù)據(jù)傳輸

CAN通信單元的組成:

每個通信單元軟件部分由數(shù)據(jù)幀、遙控幀、錯誤幀、過載幀、幀間隔組成;但不是上述5種幀都包含,具體看軟件怎樣編寫

1 數(shù)據(jù)幀的發(fā)送

1) 數(shù)據(jù)幀的組成(遙控幀與數(shù)據(jù)幀的組成類似,只是不包含數(shù)據(jù)幀的數(shù)據(jù)段)

2)STM32軟件編寫發(fā)送數(shù)據(jù)幀及解釋(遙控幀與數(shù)據(jù)幀的組成類似,只是不包含數(shù)據(jù)幀的數(shù)據(jù)段)

u8 CAN_Send_Msg(u8* msg,u8 len)

{

u8 mbox;

u16 i=0;

CanTxMsg TxMessage; //結(jié)構(gòu)體的具體元素可查找STM32數(shù)據(jù)庫手冊

TxMessage.StdId=0x12; //報文的11位標(biāo)準(zhǔn)標(biāo)識符,范圍0x000~0x7FF (設(shè)置數(shù)據(jù)幀的仲裁段的標(biāo)準(zhǔn)表示符)

//TxMessage.ExtId=0x12; //報文的29位擴展標(biāo)識符,范圍0x00000000~0x1FFFFFFF,由于IDE選擇為0,此元素可以不設(shè)置 (設(shè)置數(shù)據(jù)幀的仲裁段的擴展標(biāo)識符)

TxMessage.IDE=0; // IDE 0:選擇使用標(biāo)準(zhǔn)標(biāo)識符 1:選擇使用擴展標(biāo)識符 (設(shè)置數(shù)據(jù)幀的仲裁段的選擇)

TxMessage.RTR=0; // RTR 0:選擇發(fā)送數(shù)據(jù)幀 1:選擇發(fā)送遙控幀 (設(shè)置數(shù)據(jù)幀的控制段)

TxMessage.DLC=len; //DLC的大小為發(fā)送數(shù)據(jù)的長度,len最大為8,因為一個報文包含0~8個字節(jié)數(shù)據(jù) (設(shè)置數(shù)據(jù)幀的控制段)

for(i=0;i

TxMessage.Data[i]=msg[i]; // 給數(shù)據(jù)幀的數(shù)據(jù)賦值

mbox= CAN_Transmit(CAN1, &TxMessage);

i=0;

while((CAN_TransmitStatus(CAN1, mbox)==CAN_TxStatus_Failed)&&(i<0XFFF)) //檢測數(shù)據(jù)的發(fā)送狀態(tài)。如果失敗,等到i加到0xFFF退出循環(huán),并返回"1";成功則返回"0".

i++;

if(i>=0XFFF)

return 1;

return 0;

}

2 過濾器

在CAN協(xié)議里,報文的標(biāo)識符不代表節(jié)點的地址,而是跟報文的內(nèi)容相關(guān)的。因此,發(fā)送者以廣播的形式把報文發(fā)送給所有接受者。節(jié)點在接收報文時,根據(jù)標(biāo)識符的值,決定軟件

是否需要該報文;如果需要,就拷貝到SRAM里;如果不需要,報文就被丟棄且無需軟件的干預(yù)。

比如示意圖中: 單元1要發(fā)送報文,它會將報文發(fā)送給單元2、單元3、單元4、單元5,而單元2、單元3、單元4、單元5會根據(jù)標(biāo)識符的值,決定是否接收改報文。

為了知道哪些報文需要接收,哪些需要放棄,所以在此過程中,引入過濾器。通過過濾器來接收需要的報文。

1 幾個重要概念

1) 過濾器組

STM32總共提供14個過濾器組來處理CAN接收過濾問題,每個過濾器組包含兩個32位寄存器,即CAN_FiR0和CAN_FiR1組成(i=0~13),在設(shè)置為屏蔽位模式下,其中一個作為標(biāo)

識符寄存器,另一個作為屏蔽碼寄存器。過濾器組中的每個過濾器,編號(叫做過濾器號)從0開始,到某個最大數(shù)值(這時最大值并非13,而是取決于14個過濾器組的模式和位寬的設(shè)

置,當(dāng)全部配置為位寬為16,且為標(biāo)識符列表模式時,最大編號為14*4-1=55)。

F0R1F0R2F1R1F1R2F2R1F2R2F3R1F3R2F4R1F4R2F5R1F5R2F6R1F6R2F7R1F7R2F8R1F8R2F9R1F9R2F10R1F10R2F11R1F11R2F12R1F12R2F13R1F13R2

2 過濾器過濾模式

過濾器過濾模式有屏蔽位模式和過濾器列表模式

1)屏蔽位模式

為了過濾出一組標(biāo)識符,應(yīng)該設(shè)置過濾器組工作在屏蔽位模式;

在屏蔽位模式下,標(biāo)識符寄存器和屏蔽寄存器一起,指定報文標(biāo)識符的任何一位,應(yīng)該按照“必須匹配”或“不用關(guān)心”處理。

2)過濾器列表模式

為了過濾出一個標(biāo)識符,應(yīng)該設(shè)置過濾器組工作在標(biāo)識符列表模式;

在標(biāo)識符列表模式下,屏蔽寄存器也被當(dāng)作標(biāo)識符寄存器用。因此,不是采用一個標(biāo)識符加一個屏蔽位的方式,而是使用2個標(biāo)識符寄存器。接收報文標(biāo)識符的每一位都必須跟過濾

器標(biāo)識符相同。

3)過濾器的位寬

每個過濾器組的位寬都可以獨立配置,以滿足應(yīng)用程序的不同需求。根據(jù)位寬的不同,每個過濾器組可提供:

? 1個32位過濾器,包括:STDID[10:0]、EXTID[17:0]、IDE和RTR位

? 2個16位過濾器,包括:STDID[10:0]、IDE、RTR和EXTID[17:15]位

4)過濾器組的位寬模式和位寬設(shè)置

看手冊

5)過濾器匹配序號及優(yōu)先規(guī)則

看手冊

2 CAN ID的分析

1) CAN ID分析

標(biāo)準(zhǔn)標(biāo)識符:ID28~ID18

擴展標(biāo)識符: ID28~D18 加上 ID17~D0

eg1:有標(biāo)準(zhǔn)標(biāo)識符為:

0x6D1 (b 110 1101 0001) 占用ID的ID28~ID18,共11位

eg2:有擴展標(biāo)識符為:

0x1EFEDFEA (b 1 1110 1111 1110 1101 1111 1110 1010) 其中紅色部分為基本標(biāo)識符 粉色部分為擴展標(biāo)識符

2)位寬為32位的屏蔽模式分析

如上圖所示:此種模式下,過濾器包含一個32位的標(biāo)識符寄存器和一個32位的屏蔽寄存器,灰色部分顯示的是與CAN ID各位定位的映射關(guān)系。由圖可以看出映像關(guān)系恰好等于擴展

CAN ID左移3位再加上IDE、RTR及一個顯性電平得到。

所以如何將CAN ID所表示的各部分如何針對過濾器寄存器各部分對號入座,其主要是掌握其核心思想即可:1:在各種過濾器模式下,CAN ID與寄存器相應(yīng)位置一定要匹配;2:在

屏蔽方式下,屏蔽寄存器某位為1表示接收到的CAN ID對應(yīng)的位必須對驗證碼寄存器對應(yīng)的位相同。

eg:下面以代碼例子,假設(shè)我們要接收多個ID:0x6D1 , 1EFEDFEA, 前面為標(biāo)準(zhǔn)標(biāo)識符,后面為擴展標(biāo)識符,要同時能接收這兩個標(biāo)識符的情況來配置過濾器

u16 Std_ID =0x6D1;

u32 Ext_ID =0x1EFEDFEA;

u32 mask =0;

CAN_FilterInitTypeDef CAN_FilterInitStructure; //定義一個結(jié)構(gòu)體變量

CAN_FilterInitStructure.CAN_FilterNumber=0; //設(shè)置過濾器組0

CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //設(shè)置過濾器組0為屏蔽模式

CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //設(shè)置過濾器組0位寬為32位

/**************************************************************************************************************************************

標(biāo)識符寄存器的設(shè)置,Ext_ID<<3對齊,再>>16取高16位

***************************************************************************************************************************************/

CAN_FilterInitStructure.CAN_FilterIdHigh=((Ext_ID<<3) >>16) & 0xffff; //設(shè)置標(biāo)識符寄存器高字節(jié)。

CAN_FilterInitStructure.CAN_FilterIdLow=(u16)(Ext_ID<<3) | CAN_ID_EXT; //設(shè)置標(biāo)識符寄存器低字節(jié)

/***********************************************************************************************************************************

這里也可以這樣設(shè)置,設(shè)置標(biāo)識符寄存器高字節(jié).這里為什么是左移5位呢?從上圖可以看出,CAN_FilterIdHigh包含的是STD[0~10]和EXID[13~17],標(biāo)準(zhǔn)CAN ID本身是不包

含擴展ID數(shù)據(jù),因此為了要將標(biāo)準(zhǔn)CAN ID放入此寄存器,標(biāo)準(zhǔn)CAN ID首先應(yīng)左移5位后才能對齊。設(shè)置標(biāo)識符寄存器低字節(jié),這里也可以設(shè)置為CAN_ID_STD

CAN_FilterInitStructure.CAN_FilterIdHigh=Std_ID<<5;

CAN_FilterInitStructure.CAN_FilterIdLow=0 | CAN_ID_EXT;

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

/*************************************************************************************************************************

屏蔽寄存器的設(shè)置這里的思路是先將標(biāo)準(zhǔn)CAN ID和擴展CAN ID對應(yīng)的ID值先異或后取反,為什么?異或是為了找出兩個CAN ID有哪些位是相同的,是相同的位則說明需

要關(guān)心,需要關(guān)心的位對應(yīng)的屏蔽碼位應(yīng)該設(shè)置為1,因此需要取反一下。最后再整體左移3位。

****************************************************************************************************************************/

mask =(Std_ID<<18); //這里為什么左移18位?因為在標(biāo)準(zhǔn)CAN ID占ID18~ID28,為了與CAN_FilterIdHigh對齊,應(yīng)左移2位,接著為了與擴展

CAN對應(yīng),還應(yīng)該再左移16位,因此,總共應(yīng)左移2+16=18位。也可以用另一個方式來理解:直接看Mapping的內(nèi)容,發(fā)現(xiàn)STDID相對EXID[0]偏移了18位,因此左移18位.

mask ^=Ext_ID; //將對齊后的標(biāo)準(zhǔn)CAN與擴展CAN異或后取反

mask =~mask;

mask <<=3; //再整體左移3位

mask |=0x02; //只接收數(shù)據(jù)幀,不接收遠(yuǎn)程幀

CAN_FilterInitStructure.CAN_FilterMaskIdHigh=(mask>>16)&0xffff; //設(shè)置屏蔽寄存器高字節(jié)

CAN_FilterInitStructure.CAN_FilterMaskIdLow=mask&0xffff; //設(shè)置屏蔽寄存器低字節(jié)

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0; //此過濾器組關(guān)聯(lián)到接收FIFO0

CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活此過濾器組

CAN_FilterInit(&CAN_FilterInitStructure); //設(shè)置過濾器

3)位寬為32位的標(biāo)識符列表模式

U16 std_id =0x6D1;

U32 ext_id =0x1EFEDFEA;

CAN_FilterInitTypeDef CAN_FilterInitStructure;

CAN_FilterInitStructure.CAN_FilterNumber=0; //設(shè)置過濾器組0,范圍為0~13

CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList; //設(shè)置過濾器組0為標(biāo)識符列表模式

CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //設(shè)置過濾器組0位寬為32位

//設(shè)置屏蔽寄存器,這里當(dāng)標(biāo)識符寄存器用

CAN_FilterInitStructure.CAN_FilterIdHigh=std_id<<5) ; //為什么左移5位?與上面相同道理,這里不再重復(fù)解釋

CAN_FilterInitStructure.CAN_FilterIdLow=0|CAN_ID_STD; //設(shè)置標(biāo)識符寄存器低字節(jié),CAN_FilterIdLow的ID位可以隨意設(shè)置,在此模式下不會有效。

//設(shè)置標(biāo)識符寄存器

CAN_FilterInitStructure.CAN_FilterMaskIdHigh=((ext_id<<3)>>16) & 0xffff; //設(shè)置屏蔽寄存器高字節(jié)

CAN_FilterInitStructure.CAN_FilterMaskIdLow=((ext_id<<3)& 0xffff) | CAN_ID_EXT; //設(shè)置屏蔽寄存器低字節(jié)

CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0; //此過濾器組關(guān)聯(lián)到接收FIFO0

CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活此過濾器組

CAN_FilterInit(&CAN_FilterInitStructure); //設(shè)置過濾器

4)16位位寬屏蔽模式

5)16位位寬列表模式

6)屏蔽位模式的理解

假如過濾器組0工作在,位寬為32位標(biāo)識符屏蔽模式:

設(shè)置 CAN_F0R1=0xFFFF 0000;

CAN_F0R2=0xFF00 FF00

其中存放到 CAN_F0R1 的值是期望收到的ID,即我們希望收到的映像(STID+EXTID+IDE+RTR),最好是:FFFF 0000

而 CAN_F0R2中的0xFF00 FF00就是我們需要關(guān)心的ID,表示收到的映像。其位[31:24]和[15:8]這16個位,必須和CAN_F0R1中對應(yīng)的一模一樣,而另外的16個位則不

必關(guān)心,可以一樣也可以不一樣,都認(rèn)為是正確的ID,即收到的映像必須是0xFFXX00XX,才算是正確的(X表示不關(guān)心)。也就是說屏蔽位CAN_F0R2中的數(shù)值:

1:必須匹配,到來的標(biāo)識符位必須和過濾器對應(yīng)的標(biāo)識符寄存器位相一致

0:不關(guān)心,可以一樣,也可以不一樣,都認(rèn)為是正確的ID

因此:

為了過濾出一組標(biāo)識符,應(yīng)該設(shè)置過濾器組工作在屏蔽模式

為了過濾出一個標(biāo)識符,應(yīng)該設(shè)置過濾器組工作在標(biāo)識符列表模式

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉