CAN FD Driver-裸機模式

一、大致框架

CAN總線的系統架構,CAN總線上掛在相應的設備節點。這些設備節點包含:

  1. 最底層也就是物理層的CAN收發器(和本次使用CAN收發器有所區別,僅供參考)。
  2. 信息協議層也就是CAN控制器(和本次使用的CAN2517FD有所區別,僅供參考),主要體現在數據鏈路層這一部分。
  3. 應用程序,具體表現在控制器以不同的通信方式、MCP2517FD提供的相應指令集和指令集格式對CAN2517FD的寄存器進行讀寫操作,進而實現相應的功能。

具體可參考:CAN總線數據鏈路層分析(四)

二、CAN 控制器-MCP2517FD的瞭解

2.1 相關文檔和源碼來源於官方網站

MCP2517FD-External-CAN-FD-Controller-with-SPI-Interface-20005688B.pdf

2.2 MCP2517FD與微控制器連接示意圖

目前使用的STM32與MCP2517FD連接,MCU和CAN2517FD分別有自己的晶振(8Mhz和20Mhz)。

2.3 I/O 功能管腳

2.3.1 通信接口SPI,如上圖所示,用於和爲控制器進行通信,支持模式0和模式3。

2.3.1.1 SPI 指令格式示意圖

 

可以看出在進行數據傳輸的時候:

  1. nCS線首先要進行拉低。
  2. 接着開始進行數據傳輸,大致是4個bit的CMD,12個bit的基地址,接着就是偏移量、和N個數據了,它們最終都是以8bit的方式進行傳輸的。(具體參考下面的2.3.1.2 SPI指令集)
  3. 傳輸完成後,再將nCS線拉高。

2.3.1.2 SPI 指令集

2.3.2 時鐘

CANFD的時鐘倍/分頻都在這裏,包括波特率的相關設置,具體的操作還要看相關的寄存器配置(具體參考2.5 寄存器映射)。

2.3.3 中斷管腳

根據文檔描述,INT0和INT1分別代表發送和接收的中斷,INT中斷似乎還包括其它一些相關的功能(具體參考2.5 寄存器映射)。

 

2.3.4 發送/接收報文管腳

發送和接收報文的管腳,連接CAN的收發器。

2.4 MCP2517FD的模塊設計圖

這裏包括MCP2517FD所有的模塊:

  1. 內存(2K),用來處理相關報文等。
  2. 接收濾波器,完成接收信息的濾波。
  3. 位流處理器,用於數據流波特率相關控制。
  4. 等等這些相關功能模塊的具體功能都表現在下面“2.5 寄存器映射”上。

2.5 寄存器映射,包含了幾乎所有的CANFD的寄存器

2.5.1 模塊的基地址

2.5.2 模塊索引

2.5.2.1 MCP2517FD Specific Registers

2.5.2.2 

2.5.2.3 Message Memory

以上是所有模塊的寄存器索引

三、開發 

3.1 硬件方面

(略)

3.2 軟件方面

3.2.1 SMT32 底層驅動

主要是時鐘的配置使能、IO管腳的分配映射、模式的設置等,初始化設置。具體表現在相關函數接口:

Sys_HSE_Configuration(); 
RCC_Configuration(); //時鐘配置
GPIO_Basic_Configuration(); //IO配置
NVIC_Configuration(); //中斷配置
CAN_Configuration();

3.2.2 MCP2517FD功能封裝(數據鏈路層)

關於MCP2517FD的這一部分代碼是微芯提供的。微芯已經將關於2517的功能封裝成一個個函數、提供相應的函數接口。所有的模塊基地址以宏定義的形式定義出來,所有的寄存器都封裝成一個個的相關類型的數據。並且微芯也給出了一個相應的Demo例程,裏面包含CAN FD 的一些報文收發用法。我們直接調用即可。

3.2.3 通信方式

3.2.3.1 CAN FD 作爲Slave,STM32 作爲Master進行數據通信。

STM32和CAN FD相關的接口函數:
int8_t spi_master_transfer(uint8_t *SpiTxData, uint8_t *SpiRxData, uint16_t spiTransferSize)
{
//__disable_irq(); //關閉總中斷
SPI_CAN2517_NSEL_RESET();
for(i=0;i<spiTransferSize;i++)
{
    /* Wait for SPIx Tx buffer empty */
    while((SPI1->SR & SPI_I2S_FLAG_TXE) == (uint16_t)RESET);//檢查發送是否完成
   /* Send SPIx data */
   SPI1->DR = SpiTxData[i];

    /* Wait for SPIx data reception */
   while((SPI1->SR & SPI_I2S_FLAG_RXNE) == (uint16_t)RESET);//檢查接受標誌位 
   Delay_us(2);
   * Read SPI1 received data */
   SpiRxData[i] = SPI1->DR; 
}
SPI_CAN2517_NSEL_SET();
//__enable_irq(); //開啓總中斷
return 0;
}

參考上述 2.3.1.1 SPI 指令格式示意圖,幾乎所有的程序操作CAN FD都要用到這個函數。

3.2.3.2 CAN2517FD操作方式

參考上述2.3.1.2 SPI 指令集和 2.3.1.1 SPI 指令格式示意圖可知,CANFD 的數據傳輸方式是:4bit的CMD+12bit的Address,接着就是8bit的相應寄存器和N個Byte數據寫入了。一次傳輸1個Byte,連續傳輸N個即可,同時將會收到CAN FD返回的數據。

3.2.4 相關測試,以微芯提供的Demo爲例,類似於狀態機的形式存在。

整個源碼主要是CAN FD 方面的流程如圖(略):

具體表現在3個方面:

  1. CAN FD 設備初始化,官方源碼提供了很多關於CAN FD的接口函數,這裏只是初始化一部分。以壓縮包MCP2517FD canfdspi API for SAMV71 (v1.0)爲例,各模塊初始化函數在V71_CANFDSPI\V71_CANFDSPI\driver\canfdspi\drv_canfdspi_api.c文件裏面,需要用到其它模塊時,可以直接在 APP_CANFDSPI_Init()裏面調用即可
  2. 如何接收報文,接收報文的模式有中斷和輪詢兩種方式中斷通過STM32外部中斷的方式進入EXTI1_IRQHandler,獲取中斷的flag。輪詢的方式通過這個函數DRV_CANFDSPI_ReceiveChannelEventGet(DRV_CANFDSPI_INDEX_0, APP_RX_FIFO, &rxFlags)來獲取相應的flag。接着就是通過PC端軟件獲取相應的報文,PC端發送報文時必須是CAN FD的形式,程序裏面配置就是 FD Frame 的。DRV_CANFDSPI_ReceiveMessageGet(DRV_CANFDSPI_INDEX_0, APP_RX_FIFO, &rxObj, rxd, MAX_DATA_BYTES)獲取的相應64byte的數據,根據幀ID再像PC端軟件發送出去,用到函數:APP_TransmitMessageQueue();
  3. 如何發送報文,具體操作和 2 完全差不多有中斷和輪詢的方式,但是輪詢不需要獲取FIFO相應的狀態了直接配置幀ID、幀的各種參數配置等發送報文同樣用到:APP_TransmitMessageQueue();所有的數據指令操作程序都最終都會調用:spi_master_transfer()函數參數包含:CAN FD 芯片端口號、模塊基地址、發送數據地址、接收數據地址、數據長度。數據指令傳輸和接收放在一個 spiTransmitBuffer/spiReceiveBuffer 數組裏面,數組的長度自定義 SPI_DEFAULT_BUFFER_LENGTH = 96
  4. 詳細可參考源碼。

四、問題記錄

  1.  MCU 和 CAN FD 時鐘匹配的問題,會影響到波特率的設置、數據傳輸的穩定性。
  2. FD Frame 是 CAN 和 CAN FD模式的區別
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章