從零實現 CAN通訊 回環模式測試

2021-10-02 03:52:23 字數 3601 閱讀 7060

can是controller area network的縮寫,是iso國際標準化的序列通訊協議。是德國博世公司開發面向汽車的can通訊協議。

can控制器根據兩根線上的電位差來判斷匯流排電平。匯流排電平分為顯性電平和**電平,二者必居其一。

can協議具有以下特點:

1.多主控制,在匯流排空閒時多個單元都可以傳送訊息,而兩個單元以上同時開始傳送訊息時,根據識別符號(identifier 簡稱id)決定優先順序。id表示訪問匯流排的訊息的優先順序。優先順序高的繼續發,優先順序低的就停止傳送了。

2.系統的柔軟性。增加單元時不用改硬體,直接接上即可(速度需要與匯流排速度一致)。

3.通訊速度快,通訊距離遠。最高1mbps(小於40m),最遠可達10km(低於5kbps)

4.具有錯誤檢測、錯誤通知和錯誤恢復功能。

5.故障封閉功能。

6.連線節點多。

can協議經過iso標準化有兩個標準:iso11898(125kbps~1mbps高速通訊標準)和iso11519-2(125kbps以下低速通訊標準)。

識別符號過濾是一種過濾識別符號的功能,它可以將想接收的識別符號的過濾接收,也可以將想拒絕的識別符號過濾掉。它的存在減少了cpu處理can通訊的開銷。

stm32f429共有識別符號過濾器28組,每一組由兩個32位的暫存器,can_fxr1和can_fxr2組成。而這個32位暫存器可以根據配置為1個32位過濾器,也可以為兩個16位過濾器。

為了過濾一組識別符號,應該設定過濾器組工作在遮蔽位模式。

為了過濾乙個識別符號,應該設定過濾器組工作在識別符號列表模式。

掩碼就是對用id的哪一位需要相匹配。比如掩碼can_fxr2[7:0]:0111 1110則表示識別符號can_fxr1[7:0]的第一位和第八位不用匹配,其餘位需要匹配。

通過這個過濾器就可以讓想接收的識別符號的資料到fifo中(我們可以直接從fifo中讀接收到的資料,這就是為什麼可以節省mcu的開銷),過濾掉不想要的識別符號的資料。

stm32f429提供了兩種測試模式,環迴模式和靜默模式。如果只有乙個板子的話可以用環迴模式測can是否好用。環迴模式can把傳送的報文同時儲存在接收郵箱中(通過過濾器),也就是自收發。

正常模式,也就是兩個板子相連,乙個傳送乙個接收。但我資金有限,只有乙個板子。也沒有什麼usb轉can的東西。所以我們在實驗的時候需要有乙個從正常模式切換至環迴模式的過程。用環迴模式去測試can是否好用。

can的一包只能傳送最大8個位元組,接收最大也是8個位元組。

can我看了一遍,比較複雜的說,所以前面也只是簡單寫一下值得注意的地方,具體用到還是建議看一遍相關資料,並且再看一遍原子的實驗說明。

接下來就是直接配置cubemx實現can通訊。我們傳送固定的字串,看是否能接收到,顯示在螢幕上。

如果想要500kbps的速度,這樣配置:

已知apb1 peripheral = 45mhz,而can波特率= 45000/((bs1+bs2+1)*prescaler) = 45000/(10*6) = 500kpbs

如何知道是500kpbs呢?我們看到time for one bit經過分頻和規劃得到1999ns,那麼1/1999ns = 500kpbs。

生成**後,cubemx會生成can的初始化,但是距離傳送資料和接收資料我們還欠缺一些配置。比如指定傳送結構體指標和接收結構體指標。配置好後我們可以像串列埠一樣,在傳送前設定好傳送結構體指標。在接收後讀取接收結構體指標。

還有過濾器的配置。如果不配置的話,訊息是無法到fifo中的,我們也就讀不到了。

cantxmsgtypedef txmessage;	//傳送訊息

canrxmsgtypedef rxmessage; //接收訊息

//mode; 正常模式 can_mode_normal

// 回環模式 can_mode_loopback

void can1_init(uint32_t u32mode)

can1_filerconf.filteridhigh=0x0000; //32位id

can1_filerconf.filteridlow=0x0000;

can1_filerconf.filtermaskidhigh=0x0000; //32位mask

can1_filerconf.filtermaskidlow=0x0000;

can1_filerconf.filterfifoassignment=can_filter_fifo0;//過濾器0關聯到fifo0

can1_filerconf.filternumber=0; //過濾器0 掩碼設定為0,意味著沒有需要檢查的識別符號位

can1_filerconf.filtermode=can_filtermode_idmask;

can1_filerconf.filterscale=can_filterscale_32bit;

can1_filerconf.filteractivation=enable; //啟用濾波器0

can1_filerconf.banknumber=14;

if(hal_can_configfilter(&hcan1,&can1_filerconf)!=hal_ok) //濾波器初始化

}

傳送函式:

//can傳送一組資料(固定格式:id為0x12,標準幀,資料幀)	

//len:資料長度(最大為8)

//msg:資料指標,最大為8個位元組.

//返回值:1,成功;

// 0,失敗;

uint8_t can1_send_msg(uint8_t* pu8buff, uint8_t u8len)

接收函式:

//can口接收資料查詢

//buf:資料快取區;

//返回值:0,無資料被收到;

// 其他,接收的資料長度;

uint8_t can1_receive_msg(uint8_t *pu8buff)

在main()中實現:

1.按下key_up切換模式(正常模式-回環模式),在正常模式時led1滅,在回環模式下led1亮。

2.在回環模式下按下key1,can輸出字串text_buffer

3.按下key0更換text_buffer的內容(hello w"或"hello   ")。

4.lcd顯示接收到的字串以及傳送成功的字串。

can匯流排很「智慧型」,應用於多節點的汽車行業真的舒服,多主的特點讓優先順序高的單元擁有更高的「話語權」,檢測錯誤的功能也使匯流排更加安全。需要注意的是乙個匯流排上所有的單元速度應該一致。

雖然他的優點很多,但是缺點是一包資料只能攜帶8個位元組,在兩點間資料量大的情況下就不太試用了,。實時上,汽車上並沒有資料量很大的交流,一般的發動機轉速、故障資訊等都可以簡單地用幾個位元組表示。所以很適用於汽車這樣單元多,資料量少的環境。

從零讀懂CAN匯流排(上)

上世紀八十年代以來,汽車ecu越來越多,如abs,電控門窗,電子燃油噴射裝置。如果仍然採用常規的點對點佈線方式,即電線一段與開關相接,另一端與用電裝置相通,將會導致車上電線數目的急劇增加,從而帶來線束的冗餘及維修成本的提高。這就對汽車的線束分布及資訊通訊提出了更高的要求。匯流排技術可以實現資訊的實時...

CAN匯流排通訊的實現

實現mic 3680與f28335 can匯流排通訊的設定 mic 3680can模組濾波使用單濾波模式 can2.0a協議 使用11位識別符號 1 f28335傳送,mic 3680接收 f28335設定 1 設定msgid暫存器中ide位為0 即第31位 時,傳送標準幀 2.f28335的設定要...

從零實現 SD卡

cubemx軟體版本是v4.23.0,晶元型號是stm32f103zet6,sd卡是閃迪的64g tf卡,然後用了轉大卡的卡槽。我起初是按照原子的實驗去做,先驗證自己的sd卡是好使的。我買的閃迪64g tf卡,用tf卡轉sd卡槽,充當sd卡。stm32f103支援sdio,這個sdio就如同fmc支...