目錄
CAN介紹
CAN總線拓撲圖
CAN總線特點
CAN應用場景
CAN物理層
CAN收發器芯片介紹
?CAN協議層
數據幀介紹
CAN位時序介紹?
數據同步過程
硬件同步
?再同步
CAN總線仲裁
STM32 CAN控制器介紹
CAN控制器模式
?CAN控制器模式
?CAN控制器框圖
發送處理
接收處理
?接收過濾器
CAN控制器位時序
CAN相關寄存器介紹(F1 / F4 / F7)
CAN主控制寄存器(CAN_MCR)
CAN位時序寄存器(CAN_BTR)
CAN 標識符寄存器(CAN_(T/R)IxR)
數據長度和時間戳寄存器(CAN_(T/R)DTxR)
?CAN低位數據寄存器(CAN_(T/R)DLxR)
?CAN高位數據寄存器(CAN_(T/R)DHxR)
?CAN過濾器位寬寄存器(CAN_FS1R)
CAN 過濾器FIFO關聯寄存器(CAN_FFA1R)
CAN 過濾器組x寄存器(CAN_FxR(1/2))
CAN相關HAL庫驅動介紹
CAN外設相關重要結構體:
結構體成員與寄存器情況
CAN基本驅動步驟
過濾器組設置實例:
CAN介紹
????????CAN(Controller Area Network),是ISO國際標準化的串行通信協議。
????????為了滿足汽車產業的“減少線束的數量”、“通過多個LAN,進行大量數據的高速通信”的需求。
????????低速CAN(ISO11519)通信速率10~125Kbps,總線長度可達1000米
????????高速CAN(ISO11898)通信速率125Kbps~1Mbps,總線長度≤40米(經典CAN)
????????CAN FD 通信速率可達5Mbps,并且兼容經典CAN,遵循ISO 11898-1 做數據收發
????????更多CAN的歷史知識,可以上CAN in Automation(CiA) 官網了解。
CAN總線拓撲圖
?????????終端電阻,用于阻抗匹配,以減少回波反射
????????CAN總線由兩根線( CANL 和 CANH )組成,允許掛載多個設備節點(低速CAN:20 高速CAN:30)。
CAN總線特點
? 1)多主控制? ????????? ? ? ? 每個設備都可以主動發送數據
? 2)系統的柔軟性? ? ? ? ? ?沒有類似地址的信息,添加設備不改變原來總線的狀態
? 3)通信速度? ????????????????速度快,距離遠
? 4)錯誤檢測&錯誤通知&錯誤恢復功能
? 5)故障封閉? ????????????????判斷故障類型,并且進行隔離
? 6)連接節點多? ????????????速度與數量找個平衡
CAN應用場景
????????CAN總線協議已廣泛應用在汽車電子、工業自動化、船舶、醫療設備、工業設備等方面。
CAN物理層
????????CAN使用差分信號進行數據傳輸,根據CAN_H和CAN_L上的電位差來判斷總線電平。
????????總線電平分為顯性電平(邏輯0)和隱性電平(邏輯1),二者必居其一。
????????顯性電平具有優先權。發送方通過使總線電平發生變化,將消息發送給接收方。
電平 | 高速CAN | 低速CAN |
顯性電平(0) | UCAN_H – UCAN_L=? 2V | UCAN_H – UCAN_L = 3V |
隱性電平(1) | UCAN_H – UCAN_L = 0V | UCAN_H – UCAN_L = - 1.5V |
CAN收發器芯片介紹
?CAN協議層
????????? CAN總線以“幀”形式進行通信。CAN協議定義了5種類型的幀:數據幀、遙控幀、錯誤幀、過載幀、間隔幀,其中數據幀最為常用。
數據幀介紹
????????數據幀由7段組成。數據幀又分為標準幀(CAN2.0A)和擴展幀(CAN2.0B),主要體現在仲裁段和控制段。
CAN位時序介紹?
????????CAN總線以“位同步”機制,實現對電平的正確采樣。位數據都由四段組成:同步段(SS)、傳播時間段(PTS)、相位緩沖段1(PBS1)和相位緩沖段2(PBS2),每段又由多個位時序Tq組成。
????????注意 : 節點監測到總線上信號的跳變在SS段范圍內,表示節點與總線的時序是同步,此時采樣點的電平即該位的電平。
????????采樣點是指讀取總線電平,并將讀到的電平作為位值的點。
????????根據位時序,就可以計算CAN通信的波特率。
數據同步過程
? ? ? ? 由于時鐘頻率誤差、傳輸上的相位延遲引起偏差,所以需要數據同步
????????CAN為了實現對總線電平信號的正確采樣,數據同步分為硬件同步和再同步。
硬件同步
? ? ? ? 節點通過CAN總線發送數據,一開始發送幀起始信號。總線上其他節點會檢測幀起始信號在不在位數據的SS段內,判斷內部時序與總線是否同步。
????????假如不在SS段內,這種情況下,采樣點獲得的電平狀態是不正確的。所以,節點會使用硬件同步方式調整, 把自己的SS段平移到檢測到邊沿的地方,獲得同步,同步情況下,采樣點獲得的電平狀態才是正確的。
?再同步
????????再同步利用普通數據位的邊沿信號(幀起始信號是特殊的邊沿信號)進行同步。
????????再同步的方式分為兩種情況:超前和滯后,即邊沿信號與SS段的相對位置。
????????再同步時,PSB1和PSB2中增加或者減少的時間被稱為“再同步補償寬度(SJW)”,其范圍:1~4 Tq。
????????? 限定了SJW值后,再同步時,不能增加限定長度的SJW值。SJW值較大時,吸收誤差能力更強,但是通訊速度會下降。
????????
CAN總線仲裁
決定優先級
????????CAN總線處于空閑狀態,最先開始發送消息的單元獲得發送權。
????????多個單元同時開始發送時,從仲裁段(報文ID)的第一位開始進行仲裁。連續輸出顯性電平最多的單元可繼續發送,即首先出現隱性電平的單元失去對總線的占有權變為接收。
????????
?????????競爭失敗單元,會自動檢測總線空閑,在第一時間再次嘗試發送。
STM32 CAN控制器介紹
????????STM32 CAN控制器(bxCAN),支持CAN 2.0A 和 CAN 2.0B Active版本協議。
????????CAN 2.0A 只能處理標準數據幀且擴展幀的內容會識別錯誤,而CAN 2.0B Active 可以處理標準數據幀和擴展數據幀。CAN 2.0B Passive只能處理標準數據幀且擴展幀的內容會忽略。
bxCAN主要特點:
???波特率最高可達1M bps
???支持時間觸發通信(CAN的硬件內部定時器可以在TX/RX的幀起始位的采樣點位置生成時間戳)
???具有3級發送郵箱
???具有3級深度的2個接收FIFO
???可變的過濾器組(最多28個)(F1只有14個)
CAN控制器模式
????????CAN控制器的工作模式有三種:初始化模式、正常模式和睡眠模式。
?CAN控制器模式
CAN控制器的測試模式有三種:靜默模式、環回模式和環回靜默模式。(初始化模式下進行配置)
?CAN控制器框圖
?1)CAN內核
????????包含各種控制/狀態/配置寄存器,可以配置模式、波特率等
2)發送郵箱
????????用來緩存待發送的報文,最多可以緩存3個報文
3)接收FIFO
????????緩存接收到的有效報文
4)接收過濾器
????????篩選有效報文
發送處理
接收處理
?接收過濾器
????????當總線上報文數據量很大時,總線上的設備會頻繁獲取報文,占用CPU。過濾器的存在,選擇性接收有效報文,減輕系統負擔。
????????每個過濾器組都有兩個32位寄存器CAN_FxR1和CAN_FxR2。根據過濾器組的工作模式(位寬和選擇模式)不同,寄存器的作用不盡相同。
????????選擇模式可設置屏蔽位模式或標識符列表模式,寄存器內容的功能就有所區別。
????????屏蔽位模式,可以選擇出一組符合條件的報文。寄存器內容功能相當于是否符合條件。
????????標識符列表模式,可以選擇出幾個特定ID的報文。寄存器內容功能就是標識符本身。
????????REG中bit值代表的是匹配與否:1必須匹配 0不用關心
????????屏蔽位寄存器中位值為1,表示與ID要必須匹配;位值為0,表示可不與ID匹配。
????????在使能過濾器情況下,總線上廣播的報文ID與過濾器的配置都不匹配,CAN控制器會丟棄該報文,不會進入到接收FIFO中。
????????注意:標識符選擇位IDE和幀類型RTR需要一致。不同過濾器組的工作模式可以設置為不同。
CAN控制器位時序
STM32的CAN外設位時序分為三段:
????????同步段 SYNC_SEG、????????時間段1 BS1(PTS + PBS1)、????????時間段2 BS2
STM32F103,設TS1=8、TS2=7、BRP=3,波特率 = 36000 / [( 9 + 8 + 1 ) * 4] = 500Kbps。
STM32F407,設TS1=6、TS2=5、BRP=5,波特率 = 42000 / [( 7 + 6 + 1 ) * 6] = 500Kbps。
? 注意:通信雙方波特率需要一致才能通信成功。
CAN相關寄存器介紹(F1 / F4 / F7)
CAN主控制寄存器(CAN_MCR)
?INRQ位,用于控制初始化請求。
CAN位時序寄存器(CAN_BTR)
?STM32F103,設TS1=8、TS2=7、BRP=3,波特率 = 36000 / [( 9 + 8 + 1 ) * 4] = 500Kbps
CAN 標識符寄存器(CAN_(T/R)IxR)
?x范圍:1~3,3個發送郵箱????????????????x范圍:1~2,2個接收FIFO郵箱
?????????報文使用標準標識符,EXID[17:0]值無效
????????TxRQ位置1,請求郵箱發送
????????注意:報文使用擴展標識符時,STID[10:0]等效于EXID[28:18],與EXID[17:0]組成29位擴展標識符。
????????
數據長度和時間戳寄存器(CAN_(T/R)DTxR)
?x范圍:1~3,3個發送郵箱????????????????x范圍:1~2,2個接收FIFO郵箱
????????注意:DLC是多少,數據內容就有多少字節被發送,并不是每次都發送8個字節數據。
?CAN低位數據寄存器(CAN_(T/R)DLxR)
?CAN高位數據寄存器(CAN_(T/R)DHxR)
使用時間戳功能DLC必須為8字節
CAN過濾器模式寄存器(CAN_FM1R)
?CAN過濾器位寬寄存器(CAN_FS1R)
????????注意:CAN外設只能使用的有的過濾器組,不能使用沒有的過濾器組。?
CAN 過濾器FIFO關聯寄存器(CAN_FFA1R)
該寄存器決定了哪個FIFO寄存器有效(即RIxR、RDTxR、RDLxR、RDHxR的‘x’)。?
CAN 過濾器組x寄存器(CAN_FxR(1/2))
CAN相關HAL庫驅動介紹
CAN外設相關重要結構體:
CAN_InitTypeDef、CAN_FilterTypeDef和CAN_(T/R)xHeaderTypeDef
CAN_InitTypeDefuint32_t Prescaler /* 預分頻 */
uint32_t Mode /* 工作模式 */
uint32_t SyncJumpWidth /* 再次同步跳躍寬度 */
uint32_t TimeSeg1 /* 時間段1(BS1)長度 */
uint32_t TimeSeg2 /* 時間段2(BS2)長度 */
uint32_t TimeTriggeredMode /* 時間觸發通信模式 */
uint32_t AutoBusOff /* 總線自動關閉 */
uint32_t AutoWakeUp /* 自動喚醒 */
uint32_t AutoRetransmission /* 自動重傳 */
uint32_t ReceiveFifoLocked /* 接收FIFO鎖定 */
uint32_t TransmitFifoPriority /* 傳輸FIFO優先級 */
CAN_FilterTypeDefuint32_t FilterIdHigh /* ID高字節 */
uint32_t FilterIdLow /* ID低字節 */
uint32_t FilterMaskIdHigh /* 掩碼高字節 */
uint32_t FilterMaskIdLow /* 掩碼低字節 */
uint32_t FilterFIFOAssignment /* 過濾器關聯FIFO */
uint32_t FilterBank /* 選擇過濾器組 */
uint32_t FilterMode /* 過濾器模式*/
uint32_t FilterScale /* 過濾器位寬 */
uint32_t FilterActivation /* 過濾器使能 */
Uint32_t SlaveStartFilterBank /* 從CAN選擇啟動過濾器組 單CAN沒有意義*/
結構體成員與寄存器情況
?
CAN基本驅動步驟
1、CAN參數初始化
????????工作模式、波特率等????????HAL_CAN_Init
2、使能CAN時鐘和初始化相關引腳
????????GPIO模式設為復用功能模式????????HAL_CAN_MspInit
3、設置過濾器
????????HAL_CAN_ConfigFilter 完成過濾器的初始化
4、CAN數據接收和發送
????????HAL_CAN_AddTxMessage 發送消息
????????HAL_CAN_ GetRxMessage 接收數據
5、使能CAN相關中斷/設置NVIC/編寫中斷服務函數
????????__HAL_CAN_ENABLE_IT (可選)
過濾器組設置實例:
?
關于CAN中斷?
????????啟用 CAN 接收 FIFO0 消息掛起中斷
__HAL_CAN_ENABLE_IT(&g_can_handle_struct, CAN_IT_RX_FIFO0_MSG_PENDING);
__HAL_CAN_ENABLE_IT
:這是 STM32 HAL 庫提供的一個宏,用于啟用 CAN 外設的中斷。CAN_IT_RX_FIFO0_MSG_PENDING
:這個參數表示啟用 CAN 接收 FIFO0 消息掛起中斷。- 當 CAN 接收 FIFO0 中有新的消息并且該消息已經準備好時,控制器會觸發一個中斷,允許外部應用程序處理接收到的消息。
- FIFO(先進先出隊列)用于存儲接收到的 CAN 消息,FIFO0 是第一個 FIFO 隊列,STM32 的 CAN 控制器通常有多個 FIFO 隊列。
是的,您的理解是正確的。進入掛起中斷后,您可以讀取 can_rxheader_struct.StdId
,因為當 CAN 控制器收到數據并通過過濾器后,會將其存放到 FIFO 隊列中。中斷會在 FIFO 中有新消息時觸發,并通過 HAL 函數 HAL_CAN_GetRxMessage
將數據讀取出來。
詳細解釋:
1. CAN 接收機制概述
- CAN 總線是一個廣播式協議,當總線上有設備發送消息時,所有連接的設備都能接收到這條消息。
- 過濾器:CAN 控制器通常配置了過濾器來篩選感興趣的消息,只有經過過濾器允許的消息才會被接收并存儲到接收 FIFO 中。STM32 的 CAN 控制器可以通過配置多個過濾器來選擇哪些消息應當接收。
- FIFO 隊列:接收到的有效消息會被存儲到接收 FIFO(如 FIFO0)。消息排隊存儲,等待被中斷服務程序處理。
2. 中斷觸發
當接收到一條消息,并且通過了過濾器的檢查后,消息就會被存儲到 FIFO 中。此時,如果啟用了接收中斷(例如通過 CAN_IT_RX_FIFO0_MSG_PENDING
),并且 FIFO 中有新消息,CAN 中斷會被觸發。
3. 讀取接收的消息
- 在進入中斷處理函數
USB_LP_CAN1_RX0_IRQHandler
后,您可以通過HAL_CAN_GetRxMessage
函數讀取接收到的消息,并將消息的相關信息(如標識符)和數據存儲到相應的結構體中。 - 讀取的消息頭信息(如
StdId
、IDE
、RTR
、DLC
等)通常存儲在CAN_RxHeaderTypeDef
結構體中
4. 總結
- 數據是被動接收的:當總線上有數據并且經過了過濾器的過濾,符合條件的消息會被存儲到 FIFO 中。
- 進入中斷后,可以讀取
can_rxheader_struct.StdId
:一旦中斷被觸發,您可以通過HAL_CAN_GetRxMessage
讀取消息的標識符和數據,標識符信息存儲在can_rxheader_struct.StdId
中。 - 過濾器的作用:過濾器用于篩選總線上接收到的消息,只有符合條件的消息才會存放到 FIFO 中,并觸發中斷。