目錄
CAN協議介紹
物理層
倍訓總線網路
開環總線網路
通訊節點
差分信號
協議層簡介
CAN的波特率
位時序
幀型別、作用及格式
資料幀
STM32CAN外設
CAN 發送郵箱
CAN 接收 FIFO
有效訊息
接收處理
上溢
識別符號篩選
CAN1與CAN2整體邏輯
HAL庫函式
CAN協議介紹
物理層
CAN 通訊并不是以時鐘信號來進行同步的,它是一種異步通訊,只具有 CAN_High 和 CAN_Low 兩條信號線,共同構成一組差分信號線,以差分信號的形式進行通訊,
CAN的物理層有兩種拓撲結構,倍訓總線網路和開環總線網路,我們將依次介紹他們,
倍訓總線網路
倍訓網路的特點是:高速、近距離,
它的總線最大長度為 40m,通信速度最高為1Mbps,總線的兩端各要求有一個“120 歐”的電阻,
開環總線網路
倍訓網路的特點是:低速、遠距離,
它的最大傳輸距離為1km,最高通訊速率為 125kbps,兩根總線是獨立的、不形成倍訓,要求每根總線上各串聯有一個“2.2 千歐”的電阻,
通訊節點
CAN 總線上可以掛載多個通訊節點,節點之間的信號 經過總線傳輸,實作節點間通訊,

由于 CAN 通訊協議不對節點進行地址編碼,而是對資料內容進行編碼的,所以網路中的節點個數理論上不受限制,只要總線的負載足夠即可,可以通過中繼器增強負載,
CAN 通訊節點由一個 CAN 控制器及 CAN 收發器組成,控制器與收發器之間通過 CAN_Tx 及 CAN_Rx 信號線相連,收發器與 CAN 總線之間使用 CAN_High 及 CAN_Low 信號線相連,而 CAN_High 及 CAN_Low 是一對差分信號線,使用差分信號,
差分信號
與傳統使用單根信號線電壓表示邏輯的方式有區別,使用差分信號傳輸時,需要兩根信號線,這兩個信號線的振幅相等,相位相反,通過兩根信號線 的電壓差值來表示邏輯 0 和邏輯 1,

差分信號傳輸具有如下優點:
- 抗干擾能力強,當外界存在噪聲干擾時,幾憾訓同時耦合到兩條信號線上,所以外界的共模噪聲可以被完全抵消,
- 能有效抑制它對外部的電磁干擾,同樣的道理,由于兩根信號的極性相反,他們對外輻射的電磁場可以相互抵消,耦合的越緊密,泄放到外界的電磁能量越少,
- 時序定位精確,由于差分信號的開關變化是位于兩個信號的交點,而不像普通單端信號依靠高低兩個閾值電壓判斷,因而受工藝,溫度的影響小,能降低時序上的誤差,同時也更適合于低幅度信號的電路,
| CAN信號 | 高速CAN | 低速CAN | ||
|---|---|---|---|---|
| 電平 | 顯性 | 隱性 | 顯性 | 隱性 |
| CAN_H | 3.50 | 2.50 | 4.00 | 1.75 |
| CAN_L | 1.50 | 2.50 | 1.00 | 3.25 |
| 電位差 | 2.00 | 0 | 3.00 | -1.50 |
由于CAN總線的仲裁機制采取“線與”的方式對總線上的信號進行仲裁,因此,假如有兩個 CAN 通訊節點,在同一時間,一個輸出隱性電平,另一個輸出顯性電平,“線與”的總線仲裁機制將使它處于顯性電平狀態,因此低電平“0”被成為顯性電平,
協議層簡介
CAN的波特率
由于 CAN 屬于異步通訊,沒有時鐘信號線,連接在同一個總線網路中的各個節點會像串口異步通訊那樣,節點間使用約定好的波特率進行通訊
總線上的各個通訊節點只要約定好 1 個 Tq 的時間長度以及每一個資料位占據多少個Tq,就可以確定 CAN 通訊的波特率,
位時序
為了實作位同步,在STM32資料手冊中通過將標稱位時間劃分為以下三段
- 同步段 (SYNC_SEG):位變化應該在此時間段內發生,它只有一個時間片的固定長度 (1 x tCAN)
- 位段 1 (BS1):定義采樣點的位置,它包括 CAN 標準的 PROP_SEG 和 PHASE_SEG1, 其持續長度可以在 1 到 16 個時間片之間調整,但也可以自動加長,以補償不同網路節 點的頻率差異所導致的正相位漂移,
- 位段 2 (BS2):定義發送點的位置,它代表 CAN 標準的 PHASE_SEG2,其持續長度可 以在 1 到 8 個時間片之間調整,但也可以自動縮短,以補償負相位漂移,

關于同步,還有硬體同步、再同步等操作,更多關于位時序的內容可以參看 ISO 11898 標準,
幀型別、作用及格式
為了更有效地控制通訊,CAN 一共規定了 5 種型別的幀:

我們在這里主要介紹一下資料幀
資料幀

資料幀由 7 個段構成:
- 幀起始:表示資料幀開始的段.
- 仲裁段:表示該幀優先級的段,
- 控制段:表示資料的位元組數及保留位的段,
- 資料段:資料的內容,可發送 0~8 個位元組的資料,
- CRC段:檢查幀的傳輸錯誤的段,
- ACK段:表示確認正常接收的段,
- 幀結束:表示資料幀結束的段,
幀起始
表示幀開始的段,1 個位的顯性位,

仲裁段
表示資料的優先級的段,
標準格式和擴展格式在此的構成有所不同,

控制段
控制段由 6 個位構成,表示資料段的位元組數,標準格式和擴展格式的構成有所不同,

資料段
資料段可包含 0~8 個位元組的資料,從 MSB(最高位)開始輸出,

CRC段
CRC 段是檢查幀傳輸錯誤的幀,由 15 個位的 CRC 順序和 1 個位的 CRC 界定符(用于分隔的位)構成,

ACK段
ACK 段用來確認是否正常接收,由 ACK 槽(ACK Slot)和 ACK 界定符 2 個位構成,

幀結束
幀結束是表示該該幀的結束的段,由 7 個位的隱性位構成,

STM32CAN外設

從圖上我們可以看到,CAN 1與CAN 2為主從關系,CAN 1為Master ( 主 ) ,CAN 2為Slave ( 從 ) ,CAN 1和CAN 2有各自的3個發送郵箱,2個FIFO Buffer緩沖,6個接收郵箱,但是,28個Filter 過濾器卻是共用的,我們可以規定,哪些Filter給那個CAN用,甚至可以在程式運行的時候調控,
● CAN1:主 bxCAN,用于管理 bxCAN 與 512 位元組 SRAM 存盤器之間的通信,
● CAN2:從 bxCAN,無法直接訪問 SRAM 存盤器,
● 兩個 bxCAN 單元共享 512 位元組 SRAM 存盤器
CAN 發送郵箱
CAN 1和CAN 2有各自的3個發送郵箱,最多可以快取 3 個待發送的報文,
為了發送訊息,程式必須在請求發送之前選擇一個空的發送郵箱,使郵箱退出空的狀態,進入掛起狀態,此時,對于掛起的郵箱,軟體無法再對其訪問,進入掛起狀態后,優先級高的郵箱將優先發送,發送后的郵箱將恢復到空的狀態,

CAN 接收 FIFO
為了接收 CAN 訊息,提供了構成 FIFO 的三個郵箱,為了節約 CPU 負載,FIFO 完全由硬體進行管理,應用程式通過 FIFO 輸出郵箱訪問 FIFO 中所存盤的訊息,

有效訊息
當訊息依據 CAN 協議正確接收并且成功通過識別符號篩選后,該訊息將視為有效,
接收處理
當接收到報文時,FIFO 的報文計數器會自增,而 STM32 內部讀取 FIFO 資料之后,報文計數器會自減,我們通過狀態暫存器可獲知報文計數器的值
上溢

識別符號篩選
在 CAN 協議中,訊息的識別符號與節點地址無關,但與訊息內容有關,因此,發送器將訊息廣播給所有接收器,在接收到訊息時,接收器節點會根據識別符號的值來確定軟體是否需要該訊息,STM32 的 CAN 外設接收報文前會先使用驗收篩選器檢查,只接收需要的報文到 FIFO 中,
CAN1與CAN2整體邏輯
CAN2 外設的結構與 CAN1 外設是一樣的,他們共用篩選器且由于存盤訪問控制器由 CAN1 控制,所以要使用 CAN2 的時候必須要使能 CAN1 的時鐘,
HAL庫函式
HAL_StatusTypeDef HAL_CAN_ActivateNotification(CAN_HandleTypeDef *hcan, uint32_t ActiveITs);
- 引數
hcan:指向CAN配置結構體ActiveITs:表明哪個中斷會被啟動,開啟改中斷的訊息提示
- 回傳值
HAL_StatusTypeDef:如果開啟成功,回傳HAL_OK;如果失敗,回傳HAL_ERROR
HAL_StatusTypeDef HAL_CAN_Start(CAN_HandleTypeDef *hcan);
- 引數
hcan:指向CAN配置結構體
- 回傳值
HAL_StatusTypeDef:如果開啟成功,回傳HAL_OK;如果失敗,回傳HAL_ERROR
HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef *hcan, CAN_FilterTypeDef *sFilterConfig);
- 引數
hcan:指向CAN配置結構體sFilterConfig:指向Filter過濾器配置結構體
- 回傳值
HAL_StatusTypeDef:如果開啟成功,回傳HAL_OK;如果失敗,回傳HAL_ERROR
HAL_StatusTypeDef HAL_CAN_AddTxMessage(CAN_HandleTypeDef *hcan, CAN_TxHeaderTypeDef *pHeader, uint8_t aData[], uint32_t *pTxMailbox);
- 引數
hcan:指向CAN配置結構體pHeader:指向發送資料的配置結構體aData[]:指向需要發送的資料pTxMailbox:該函式會回傳用于儲存發送資料的發送郵箱編號到該變數
- 回傳值
HAL_StatusTypeDef:如果添加成功,回傳HAL_OK;如果失敗,回傳HAL_ERROR
uint32_t HAL_CAN_IsTxMessagePending(CAN_HandleTypeDef *hcan, uint32_t TxMailboxes);
- 引數
hcan:指向CAN配置結構體TxMailboxes:指向發送資料的發送郵箱
- 回傳值
uint32_t:如果有發送資料正在等待發送,回傳1;如果沒有,回傳0
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan);
- 在寫代碼的時候,在
main.c中創建HAL_CAN_RxFifo0MsgPendingCallback函式 - 在該函式中填寫在FIFO 0中已經沒有正在等待接收的資料的時候開啟中斷,需要執行的代碼
HAL_StatusTypeDef HAL_CAN_GetRxMessage(CAN_HandleTypeDef *hcan, uint32_t RxFifo, CAN_RxHeaderTypeDef *pHeader, uint8_t aData[]);
- 引數
hcan:指向CAN配置結構體RxFifo:指向負責接收的FIFOpHeader:指向接收資料的配置結構體aData[]:指向需要接收的資料
- 回傳值
HAL_StatusTypeDef:如果接收成功,回傳HAL_OK;如果失敗,回傳HAL_ERROR
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/297922.html
標籤:其他
下一篇:第一節·導讀與通用開發歷程
