1?
FlexCAN簡介
FlexCAN模塊是一個通信控制器,擴展了CAN FD功能,遵循ISO 11898-1標準、CAN FD和CAN 2.0B協議規范。 CAN協議主要被設計用作車載串行總線,滿足實時處理,帶寬要求,車輛在電磁干擾環境下的可靠操作,該模塊支持標準和擴展幀,支持最大64字節有效負載,傳輸速率高達 8Mbps,并且具有非常靈活的用于傳輸和接收的郵箱系統和RxFIFO接收機制。郵箱系統由 32 個報文緩沖區(MB)組成。
2?
FlexCAN的功能框圖
FlexCAN 的功能框圖如下圖1所示,包括用于存儲報文緩沖區(MB)、接收全局掩碼寄存器、接收私有掩碼寄存器、接收(Rx) FIFO 過濾器以及接收 FIFO 標識符過濾器的內存。
圖1 FlexCAN功能框圖
如上圖1所示為FlexCAN的功能框圖,協議引擎(PE)子模塊管理 CAN 總線上的串行通信:
請求存取 RAM 接收和傳輸幀
驗收接收到的報文
進行錯誤處理
檢測 CAN FD 報文
控制器主機接口(CHI)子模塊負責選擇接收和傳輸的報文緩沖區,以及對報文的仲裁和 ID 匹配算法。
總線接口單元(BIU)子模塊控制內部接口總線的訪問,建立與 CPU 和其他模塊的連接。時鐘、地址和數據總線、中斷輸出、 DMA 都通過 BIU 進行訪問。
3?
FlexCAN的時鐘
如下圖2所示為產生 PE 時鐘的電路結構。時鐘源選擇位(CAN_CTRL1.CLKSRC)定義了內部時鐘為異步時鐘或同步時鐘。其中,同步時鐘為外設時鐘(由APB1總線時鐘提供);異步時鐘的時鐘源可選(細節請參考 RCC 章節 RCC_CFGR2寄存器)。為保證可靠運行,應在模塊禁止模式時(CAN_MCR.MDIS 置位)選擇時鐘源。
圖2 FlexCAN的PE時鐘結構
4?
FlexCAN的協議時序
FlexCAN支持多種方式來設置 CAN 協議所要求的位時序參數。控制寄存器 1(CAN_CTRL1)有各種用于控制位時序參數的字段: PRESDIV、 PROPSEG、 PSEG1、 PSEG2 和 RJW。 CAN 位時序寄存器(CAN_CBT)擴展了 CAN_CTRL1 中 CAN 位時序變量的范圍。 CAN_FDCBT 提供了用于 BRS 置位的 CAN FD 幀數據段的位時序變量。
CAN FD 使能時,應始終置位 CAN_CBT.BTF 或 CAN_CTRL2.BTE,并在 CAN_CBT 中配置CAN 位時序變量。
PRESDIV字段(及其擴展范圍 EPRESDIV 和用于 CAN FD 報文數據段的 FDPRESDIV)定義了
串行時鐘(Sclock)的預分頻(見下列方程)。串行時鐘的周期定義了用于構成 CAN 波形的時間單位 Tq(Time Quantum)。 Tq 為 CAN 引擎所能處理的最小時間單元。
比特率定義了接收或傳輸 CAN 報文的速率,公式如下:
FlexCAN的位時間可細分為三個部分:
同步段(SYNC_SEG)
1Tq 的固定長度;信號邊沿出現在該段內。
時間段 1
包括 CAN 標準的傳播段和相位段1。該段可通過設置 CAN_CTRL1 寄存器的PROPSEG和PSEG1 字段來編程,其總和(+2)為 2 ~ 16Tq。當 CAN_CBT.BTF 被置位時,FlexCAN 使用來自 CAN_CBT 寄存器的EPROPSEG和EPSEG1 字段,其總和(+2)為 2~ 96Tq 。對于BRS置位的CAN FD報文,FlexCAN使用CAN_FDCBT寄存器的FDPROPSEG 和 FDPSEG1 字段,其總和為 2 ~ 39Tq。
時間段 2
CAN 標準的相位段2。該段可通過設置CAN_CTRL1寄存器的PSEG2字段來編程,其值(+1)為 2 ~ 8Tq。當CAN_CBT.BTF被置位時, FlexCAN使用來自CAN_CBT寄存器的EPSEG2字段,其值(+1)為 2 ~ 32Tq。對于BRS置位的 CAN FD 報文, FlexCAN使用CAN_FDCBT寄存器的FDPSEG2字段,其值(+1)為 2 ~ 8Tq。時間段2不能小于信息處理時間(IPT),IPT 在 FlexCAN 中為 2Tq。
注意事項:
FPRESDIV 定義了 BRS 置位的 CAN FD 幀數據比特率部分的PE時鐘頻率和串行時鐘(Sclock)頻率之間的比率。 Sclock 周期定義了CAN FD協議數據比特率的 Tq。Sclock 頻率 = PE 時鐘頻率 /(FPRESDIV + 1)注:為避免處理FD幀時出錯, FPRESDIV 和PRESDIV(CAN_CBT 或 CAN_CTRL1)請使用相同的值。FPRESDIV 只能在凍結模式下寫入,其他模式下被硬件鎖定。
如下圖3所示為FlexCAN位時間內的段使用 CAN_CTRL1位時序變量的經典 CAN 格式。
圖3
如下圖4所示為FlexCAN FD位時間內的段,使用CAN FD格式的CAN_CBT和CAN_FDCBT位時序變量,其中FlexCAN FD的仲裁段使用經典CAN格式配置位時間,即使用CAN_CBT位時序變量用于配置仲裁段的位時間,FlexCAN FD的可變速率的位時間使用CAN_FDCBT位時序變量配置。
圖4
FlexCAN的語法說明如下表1所示:
表1
當采用CAN位作為持續時間的衡量標準時(例如,評估報文中的CAN位事件),一個 CAN 位的外設時鐘個數(NumClkBit)為:
其中:
NumClkBit 為一個 CAN 位的外設時鐘個數
fSYS 為系統(CHI)時鐘頻率,單位 Hz
PSEG1 為 CAN_CTRL1.PSEG1 的值
PSEG2 為 CAN_CTRL1.PSEG2 的值
PROPSEG 為 CAN_CTRL1.PROPSEG 的值
PRESDIV 為 CAN_CTRL1.PRESDIV 的值
上述公式也適用于 CAN 位時序寄存器(CAN_CBT)所述的 CAN 位時間變量。
因此,FlexCAN FD仲裁段使用經典CAN位的速率計算公式為:
FlexCAN FD可變速率數據段的計算公式為:
fCANCLK為PE時鐘,單位Hz
BITRATEN是由CAN 標稱位時間變量計算出的 CAN 位速率,單位bps
BITRATEF是由CAN 數據位時間變量計算出的CAN位速率,單位bps
EPSEG1為CAN_CBT.EPSEG1的值(也可使用 CAN_CTRL1.PSEG1)
EPSEG2 為 CAN_CBT.EPSEG2 的值(也可使用 CAN_CTRL1.PSEG2)
EPROPSEG 為CAN_CBT.EPROPSEG 的值(也可使用 CAN_CTRL1.PROPSEG)
EPRESDIV 為CAN_CBT.EPRESDIV 的值(也可使用 CAN_CTRL1.PRESDIV)
那么CAN FD幀標稱比特率相應的每個CAN位的外設時鐘數量CPCBN為:
CAN FD 幀數據比特率相應的每個CAN位的外設時鐘數量CPCBF為:
因此在已知FlexCAN FD時鐘和預分頻系數以及波特率的情況下可以計算出FlexCAN FD的標稱位時間TqN總數和可變速率數據位時間TqF總數,計算公式分別如下所示:
fcanclk / BITRATEN x (EPRESDIV+1) = [1+(EPSEG1+1)+(EPSEG2+1)+(EPROPSEG+1)]
fcanclk / BITRATEF x (FPRESDIV+1) = [1+(FPSEG1+1)+(FPSEG2+1)+FPROPSEG]
根據以上FlexCAN FD的位時序可知可以分別根據標稱位時間TqN總數和可變速率數據位時間TqF總數分別計算出其標稱位時間的采樣點和可變速率數據位時間的采樣點,即FlexCAN FD標稱位時間的采樣點的計算公式為:
FlexCAN_samplepoint = (SYNC_SEG+(EPROPSEG+1) +(EPSEG1+1) )/ (SYNC_SEG+(EPROPSEG+1) +(EPSEG1+1)+ (EPSEG2+1))
FlexCAN FD可變速率位時間的采樣點的計算公式為:
FlexCAN_FDsamplepoint = (SYNC_SEG+FPROPSEG+(FPSEG1+1) )/ (SYNC_SEG+FPROPSEG+(FPSEG1+1)+ (FPSEG2+1))
5?
FlexCAN FD位時間采樣點的計算
根據以上4章節FlexCAN的位時間描述以及FlexCAN FD位時間和采樣點的計算公式推導,在給定FlexCAN FD時鐘和波特率以及分頻系數的情況下,可以使用FlexCAN的庫函數通過循環遍歷的方式實現自動計算FlexCAN FD的位時間的采樣點。
FlexCAN FD庫函數定義的協議時序代碼如下所示:
typedefstruct_flexcan_timing_config{ u16preDivider;/*!
FlexCAN FD標稱位時間采樣點和可變速率采樣點的位時間的計算,可以通過循環遍歷方式實現自動計算,代碼如下所示:
boolFLEXCAN_FDCalculateImprovedTimingValues(uint32_tbaudRate,uint32_tbaudRateFD,uint32_tsourceClock_Hz,flexcan_timing_config_t*pTimingConfig) { boolfgRet=false; pTimingConfig->preDivider=0U; pTimingConfig->fpreDivider=0U; if(FLEXCAN_CalculateImprovedTimingValuesByFDCBT(baudRateFD,sourceClock_Hz,pTimingConfig)) { if(FLEXCAN_CalculateImprovedTimingValuesByCBT(baudRate,sourceClock_Hz,pTimingConfig)) { fgRet=true; } } return(fgRet); } staticboolFLEXCAN_CalculateImprovedTimingValuesByFDCBT(uint32_tbaudRate,uint32_tsourceClock_Hz,flexcan_timing_config_t*pTimingConfig) { uint32_tclk;/*theclockistqNumbxbaudRateFD.*/ uint32_ttqNum;/*NumbersofTQ.*/ boolfgRet=false; tqNum=FDCBT_MAX_TIME_QUANTA; /*AutoImprovedProtocaltiming.*/ do { clk=baudRate*tqNum; if(clk>sourceClock_Hz) { continue;/*tqNumtoolarge,clkhasbeenexceedsourceClock_Hz.*/ } if((sourceClock_Hz/clk*clk)!=sourceClock_Hz) { continue;/*Non-supporting:thefrequencyofclocksourceisnotdivisiblebytargetbaudrate,theuser shouldchangeadivisiblebaudrate.*/ } /*Makesurethenewcalculateddividervalueisgreaterthanthepreviousone.*/ if(pTimingConfig->fpreDivider>((uint16_t)(sourceClock_Hz/clk)-1U)) { continue; } else { pTimingConfig->fpreDivider=(uint16_t)(sourceClock_Hz/clk)-1U; } if(pTimingConfig->fpreDivider>MAX_FPRESDIV) { break;/*Thefrequencyofsourceclockistoolargeorthebaudrateistoosmall,thepre-dividercould nothandleit.*/ } /*Trytogetthebesttimingconfiguration.*/ if(FLEXCAN_FDGetSegmentswithBRS(baudRate,tqNum,pTimingConfig)) { fgRet=true; break; } } while(--tqNum>=FDCBT_MIN_TIME_QUANTA); return(fgRet); } staticboolFLEXCAN_FDGetSegmentswithBRS(uint32_tbaudRatebrs,uint32_ttqNum,flexcan_timing_config_t*pTimingConfig) { uint32_tideal_sp; uint32_tp1; boolfgRet=false; /*getidealsamplepoint.*/ if(baudRatebrs>=1000000U) { ideal_sp=IDEAL_SP_LOW; } elseif(baudRatebrs>=800000U) { ideal_sp=IDEAL_SP_MID; } else { ideal_sp=IDEAL_SP_HIGH; } /*distributetimequanta.*/ p1=tqNum*(uint32_t)ideal_sp; pTimingConfig->fpropSeg=(uint8_t)(p1/(uint32_t)IDEAL_SP_FACTOR-2U); if(pTimingConfig->fpropSeg<=?(MAX_FPSEG1?+?MAX_FPROPSEG)) ????{ ????????if?(pTimingConfig->fpropSeg>MAX_FPROPSEG) { pTimingConfig->fphaseSeg1=pTimingConfig->fpropSeg-MAX_FPROPSEG; pTimingConfig->fpropSeg=MAX_FPROPSEG; } else { pTimingConfig->fphaseSeg1=0; } if(pTimingConfig->fphaseSeg1<=?MAX_PSEG1) ????????{ ????????????if?((pTimingConfig->fpropSeg+pTimingConfig->fphaseSeg1)((uint8_t)tqNum?-?3U)) ????????????{ ????????????????pTimingConfig->fphaseSeg2=(uint8_t)tqNum-(pTimingConfig->fphaseSeg1+pTimingConfig->fpropSeg+3U); if(pTimingConfig->fphaseSeg2<=?MAX_PSEG2) ????????????????{ ????????????????????if?((pTimingConfig->fphaseSeg1fphaseSeg2)&&(pTimingConfig->fpropSeg>(pTimingConfig->fphaseSeg2-pTimingConfig->fphaseSeg1))) { pTimingConfig->fpropSeg-=(pTimingConfig->fphaseSeg2-pTimingConfig->fphaseSeg1); pTimingConfig->fphaseSeg1=pTimingConfig->fphaseSeg2; } /*subtractoneTQforsyncseg.*/ /*sjwis20%oftotalTQ,roundedtonearestint.*/ pTimingConfig->frJumpwidth=((uint8_t)tqNum+4U)/5U-1U; if(pTimingConfig->frJumpwidth>MAX_FRJW) { pTimingConfig->frJumpwidth=MAX_FRJW; } fgRet=true; } } } } return(fgRet); } staticboolFLEXCAN_CalculateImprovedTimingValuesByCBT(uint32_tbaudRate,uint32_tsourceClock_Hz,flexcan_timing_config_t*pTimingConfig) { uint32_tclk;/*theclockistqNumbxbaudRateFD.*/ uint32_ttqNum;/*NumbersofTQ.*/ boolfgRet=false; tqNum=CBT_MAX_TIME_QUANTA; /*AutoImprovedProtocaltiming.*/ do { clk=baudRate*tqNum; if(clk>sourceClock_Hz) { continue;/*tqNumtoolarge,clkhasbeenexceedsourceClock_Hz.*/ } if((sourceClock_Hz/clk*clk)!=sourceClock_Hz) { continue;/*Non-supporting:thefrequencyofclocksourceisnotdivisiblebytargetbaudrate,theuser shouldchangeadivisiblebaudrate.*/ } /*Makesurethenewcalculateddividervalueisgreaterthanthepreviousone.*/ if(pTimingConfig->preDivider>((uint16_t)(sourceClock_Hz/clk)-1U)) { continue; } else { pTimingConfig->preDivider=(uint16_t)(sourceClock_Hz/clk)-1U; } /*TominimizeerrorswhenprocessingFDframes,trytocalculatethesamevalueforFPRESDIVandPRESDIV(inCBT).*/ if(pTimingConfig->preDivider!=pTimingConfig->fpreDivider) { continue; } if(pTimingConfig->preDivider>MAX_EPRESDIV) { break;/*Thefrequencyofsourceclockistoolargeorthebaudrateistoosmall,thepre-dividercould nothandleit.*/ } /*Trytogetthebesttimingconfiguration.*/ if(FLEXCAN_FDGetSegments(baudRate,tqNum,pTimingConfig)) { fgRet=true; break; } } while(--tqNum>=CBT_MIN_TIME_QUANTA); return(fgRet); }
FlexCAN FD位時間采樣點應用舉例,本文示例以MM32F0160的FlexCAN FD外設為例,其中FlexCAN FD的標稱波特率為500K,可變速率波特率為2MHz。fCAN的時鐘為72MHz,把FlexCAN FD的fCAN時鐘,標稱波特率500K,可變速率波特率2MHz代入庫函數FLEXCAN_FDCalculateImprovedTimingValues分別計算得出FlexCAN FD標稱波特率和可變速率波特率的位時間參數如下:
標稱波特率的位時間參數:
preDivider = 0x01;
propSeg = 0x34;
phaseSeg1 = 0x08;
phaseSeg2 = 0x08;
rJumpwidth = 0x0E
可變速率波特率位時間參數:
fpreDivider = 0x01;
fpropSeg = 0x07;
fphaseSeg1 = 0x04;
fphaseSeg2 = 0x04;
frJumpwidth = 0x03
注:再同步參數rJumpwidth 和frJumpwidth不參與FlexCANFD采樣點的計算
又因為在已知FlexCAN FD時鐘和預分頻系數,以及波特率的情況下可以計算出FlexCAN FD的標稱位時間TqN總數和可變速率數據位時間TqF總數,計算公式分別如下所示:
標稱位時間TqN總數:
fcanclk / BITRATEN x (EPRESDIV+1) = [1+(EPSEG1+1)+(EPSEG2+1)+(EPROPSEG+1)]
代入自動計算得出的標稱波特率500K的位時間參數,計算出TqN:
TqN = 72000000/500000x(1+1)= 72
可變速率數據位時間TqF總數:
fcanclk / BITRATEF x (FPRESDIV+1) = [1+(FPSEG1+1)+(FPSEG2+1)+FPROPSEG]
代入自動計算得出的可變波特率2MHz的位時間參數,計算出TqF:
TqF = 72000000/2000000x(1+1)= 18
根據以上FlexCAN FD使用庫自動計算出的位時間參數,以及標稱位時間TqN總數和可變速率位時間TqF總數,可以分別計算出其標稱位時間的采樣點和可變速率數據位時間的采樣點,即FlexCAN FD標稱位時間的采樣點的計算公式為:
FlexCAN_samplepoint = (SYNC_SEG+(EPROPSEG+1) +(EPSEG1+1) )/ (SYNC_SEG+(EPROPSEG+1) +(EPSEG1+1)+ (EPSEG2+1))
代入標稱波特率500K的位時間參數計算標稱波特率的位時間的采樣點如下:
FlexCAN_samplepoint =(1+(52+1)+(8+1))/(1+(52+1)+(8+1)+(8+1))= 87.5%
FlexCAN FD可變速率位時間的采樣點的計算公式為:
FlexCAN_FDsamplepoint = (SYNC_SEG+FPROPSEG+(FPSEG1+1) )/ (SYNC_SEG+FPROPSEG+(FPSEG1+1)+ (FPSEG2+1))
代入可變速率2MHz波特率的位時間參數計算可變速率的位時間的采樣點如下:
FlexCAN_FDsamplepoint = (1+7+(4+1))/(1+7+(4+1)+(4+1))= 72%
CAN采樣點一般設置在75%—80%之間,具體要根據CAN通信波特率大小配置。當波特率不超過500K時,建議采樣點設置在87.5%;當波特率大小在500K—800K之間的時候,建議采樣點設置在80%;當波特率大于800K的時候,建議采樣點設置在75%。以上建議并不是絕對的,需根據應用環境復雜程度通過調整FlexCAN FD的再同步參數rJumpwidth和frJumpwidth使得phaseSeg1和phaseSeg2以及fphaseSeg1和fphaseSeg2在標稱波特率和可變波特率的位時間上前移或后移N(0-15)個Tq值來微調采樣點(雖然rJumpwidth和frJumpwidth不參與采樣點計算)。
注意事項:
關于采樣點的配置的一些額外建議:當用戶在實際車用環境中出現FlexCAN無正常收發數據時除了根據錯誤標志查找問題定位問題外,還可使用專業的CAN診斷儀測試出多節點總線上的rJumpwidth和frJumpwidth,phaseSeg1和phaseSeg2以及fphaseSeg1和fphaseSeg2參數,參考這些位時間參數值來調整適配rJumpwidth和frJumpwidth,phaseSeg1和phaseSeg2以及fphaseSeg1和fphaseSeg2參數到CAN通信的合適的采樣點。
審核編輯:劉清
-
緩沖器
+關注
關注
6文章
1917瀏覽量
45449 -
CAN
+關注
關注
57文章
2715瀏覽量
463364 -
接收機
+關注
關注
8文章
1179瀏覽量
53407 -
FIFO芯片
+關注
關注
0文章
10瀏覽量
8802
原文標題:靈動微課堂 (第277講)|MM32F0160的FlexCAN FD位時間采樣點的計算
文章出處:【微信號:MindMotion-MMCU,微信公眾號:靈動MM32MCU】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論