CAN bus長得有點像是I2C,也長得有點像是RS485,但我覺得更合是合體的protocol,我覺得CAN bus是一個非常適合傳嚴謹的protocol,如果有興趣看CAN bus的protocol,應該可以找其他的介紹,應該會比我介紹的完整,這篇主要是介紹我在STM32上遇到的一些困難和記錄。
下圖是一個一般常見的CAN bus 使用方法,MCU接了一顆CAN transceiver,這也是normal mode的CAN bus。
CAN bus有三個測試 mode,用來自我測試程式是否有問題,比較常用的會是loop back, 如果使用normal mode 又沒有接CAN transceiver IC 也沒有接對應的CAN 的話,那麼就會無法通訊,通訊會fail。 原因是因為normal mode 需要有對應的CAN 來做ACK的動作,但如果是loop back就沒有這個問題,所以可以自我測試。
在STM32 cubeMX 產生出來的code,最重要的就是要調整CAN 的頻率,而頻率的調整就是要靠Time Quanta in bit segment 1 / Time Quanta in bit segment 2 和 ReSynchronization Jump Width這3個參數來決定,以我們的應用是500Khz,就要調出2000ns,這個很重要,如果頻率調錯了,是無法通訊的。
記得把RX的interrupt 打開,STM32的RX有support 2個FIFO,主要要看初始化如何設定,像我只需要1個FIFO,就只開FIFO0就好。
if (HAL_CAN_Receive_IT(&hcan1, CAN_FIFO0) != HAL_OK)
{
/* Reception Error */
OEM_Error_Handler(HAL_CAN1_ERROR);
}
會有2個FIFO的需求是因為CAN bus 可能會有很多interrupt,怕MCU太忙,可以用2個FIFO來分擔一下MCU的負擔,有點像是ping-pong buffer。
因為CAN bus 可以並接很多device,bus 上可能會非常的busy,如果每個ID都去檢查,這樣會造成MCU的負擔,所以我們只要檢查自己的ID就好,那麼就需做filter的動作,也就是說,只有屬於自己有關係的ID 才要去處理,其他的就都一概不理會,下面是STM32設計的filter架構: CAN 能設的組數很多, 也有分很多種模式, ID MASK 和 ID List, ID MASK 是選擇那些BIT 是否需要FILTER , ID LIST 像是白名單, 就是需要完全符合ID才行。
程式上,filterNumber 就是那個filter,BankNumber是指CAN 2由那個filter 開始。
這裡要補充一下,STM32 的dual CAN 並非2個獨立的CAN bus,而是CAN 1和 CAN 2 share 相關的register,主要就是filter的部分,因為是share的,所可以透過firmware 來做分配,但有一點一定要注意,CAN 2不能單獨使用,一定要enable CAN 1 才有辦法使用。
如果使用的是STM32F1 系列,請注意下面這個說明,白話文就是,CAN 和 USB 因為共用RAM,所以同個案子可以用USB和CAN,但是絕對不能同時使用!!!
因為我們需要dual CAN,本來選用STM32F105,但因為我們需要USB 也需要CAN bus,所以後來是選用STM32F412,除了功能更強之外,最意外的收獲就是這顆還非常省電的!