1?
FlexCAN簡介
FlexCAN模塊是一個通信控制器,擴(kuò)展了CAN FD功能,遵循ISO 11898-1標(biāo)準(zhǔn)、CAN FD和CAN 2.0B協(xié)議規(guī)范。 CAN協(xié)議主要被設(shè)計用作車載串行總線,滿足實時處理,帶寬要求,車輛在電磁干擾環(huán)境下的可靠操作,該模塊支持標(biāo)準(zhǔn)和擴(kuò)展幀,支持最大64字節(jié)有效負(fù)載,傳輸速率高達(dá) 8Mbps,并且具有非常靈活的用于傳輸和接收的郵箱系統(tǒng)和RxFIFO接收機(jī)制。郵箱系統(tǒng)由 32 個報文緩沖區(qū)(MB)組成。
2?
FlexCAN的功能框圖
FlexCAN 的功能框圖如下圖1所示,包括用于存儲報文緩沖區(qū)(MB)、接收全局掩碼寄存器、接收私有掩碼寄存器、接收(Rx) FIFO 過濾器以及接收 FIFO 標(biāo)識符過濾器的內(nèi)存。
圖1 FlexCAN功能框圖
如上圖1所示為FlexCAN的功能框圖,協(xié)議引擎(PE)子模塊管理 CAN 總線上的串行通信:
請求存取 RAM 接收和傳輸幀
驗收接收到的報文
進(jìn)行錯誤處理
檢測 CAN FD 報文
控制器主機(jī)接口(CHI)子模塊負(fù)責(zé)選擇接收和傳輸?shù)膱笪木彌_區(qū),以及對報文的仲裁和 ID 匹配算法。
總線接口單元(BIU)子模塊控制內(nèi)部接口總線的訪問,建立與 CPU 和其他模塊的連接。時鐘、地址和數(shù)據(jù)總線、中斷輸出、 DMA 都通過 BIU 進(jìn)行訪問。
3?
FlexCAN的時鐘
如下圖2所示為產(chǎn)生 PE 時鐘的電路結(jié)構(gòu)。時鐘源選擇位(CAN_CTRL1.CLKSRC)定義了內(nèi)部時鐘為異步時鐘或同步時鐘。其中,同步時鐘為外設(shè)時鐘(由APB1總線時鐘提供);異步時鐘的時鐘源可選(細(xì)節(jié)請參考 RCC 章節(jié) RCC_CFGR2寄存器)。為保證可靠運(yùn)行,應(yīng)在模塊禁止模式時(CAN_MCR.MDIS 置位)選擇時鐘源。
圖2 FlexCAN的PE時鐘結(jié)構(gòu)
4?
FlexCAN的協(xié)議時序
FlexCAN支持多種方式來設(shè)置 CAN 協(xié)議所要求的位時序參數(shù)。控制寄存器 1(CAN_CTRL1)有各種用于控制位時序參數(shù)的字段: PRESDIV、 PROPSEG、 PSEG1、 PSEG2 和 RJW。 CAN 位時序寄存器(CAN_CBT)擴(kuò)展了 CAN_CTRL1 中 CAN 位時序變量的范圍。 CAN_FDCBT 提供了用于 BRS 置位的 CAN FD 幀數(shù)據(jù)段的位時序變量。
CAN FD 使能時,應(yīng)始終置位 CAN_CBT.BTF 或 CAN_CTRL2.BTE,并在 CAN_CBT 中配置CAN 位時序變量。
PRESDIV字段(及其擴(kuò)展范圍 EPRESDIV 和用于 CAN FD 報文數(shù)據(jù)段的 FDPRESDIV)定義了
串行時鐘(Sclock)的預(yù)分頻(見下列方程)。串行時鐘的周期定義了用于構(gòu)成 CAN 波形的時間單位 Tq(Time Quantum)。 Tq 為 CAN 引擎所能處理的最小時間單元。
比特率定義了接收或傳輸 CAN 報文的速率,公式如下:
FlexCAN的位時間可細(xì)分為三個部分:
同步段(SYNC_SEG)
1Tq 的固定長度;信號邊沿出現(xiàn)在該段內(nèi)。
時間段 1
包括 CAN 標(biāo)準(zhǔn)的傳播段和相位段1。該段可通過設(shè)置 CAN_CTRL1 寄存器的PROPSEG和PSEG1 字段來編程,其總和(+2)為 2 ~ 16Tq。當(dāng) CAN_CBT.BTF 被置位時,F(xiàn)lexCAN 使用來自 CAN_CBT 寄存器的EPROPSEG和EPSEG1 字段,其總和(+2)為 2~ 96Tq 。對于BRS置位的CAN FD報文,F(xiàn)lexCAN使用CAN_FDCBT寄存器的FDPROPSEG 和 FDPSEG1 字段,其總和為 2 ~ 39Tq。
時間段 2
CAN 標(biāo)準(zhǔn)的相位段2。該段可通過設(shè)置CAN_CTRL1寄存器的PSEG2字段來編程,其值(+1)為 2 ~ 8Tq。當(dāng)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 幀數(shù)據(jù)比特率部分的PE時鐘頻率和串行時鐘(Sclock)頻率之間的比率。 Sclock 周期定義了CAN FD協(xié)議數(shù)據(jù)比特率的 Tq。Sclock 頻率 = PE 時鐘頻率 /(FPRESDIV + 1)注:為避免處理FD幀時出錯, FPRESDIV 和PRESDIV(CAN_CBT 或 CAN_CTRL1)請使用相同的值。FPRESDIV 只能在凍結(jié)模式下寫入,其他模式下被硬件鎖定。
如下圖3所示為FlexCAN位時間內(nèi)的段使用 CAN_CTRL1位時序變量的經(jīng)典 CAN 格式。
圖3
如下圖4所示為FlexCAN FD位時間內(nèi)的段,使用CAN FD格式的CAN_CBT和CAN_FDCBT位時序變量,其中FlexCAN FD的仲裁段使用經(jīng)典CAN格式配置位時間,即使用CAN_CBT位時序變量用于配置仲裁段的位時間,F(xiàn)lexCAN FD的可變速率的位時間使用CAN_FDCBT位時序變量配置。
圖4
FlexCAN的語法說明如下表1所示:
表1
當(dāng)采用CAN位作為持續(xù)時間的衡量標(biāo)準(zhǔn)時(例如,評估報文中的CAN位事件),一個 CAN 位的外設(shè)時鐘個數(shù)(NumClkBit)為:
其中:
NumClkBit 為一個 CAN 位的外設(shè)時鐘個數(shù)
fSYS 為系統(tǒng)(CHI)時鐘頻率,單位 Hz
PSEG1 為 CAN_CTRL1.PSEG1 的值
PSEG2 為 CAN_CTRL1.PSEG2 的值
PROPSEG 為 CAN_CTRL1.PROPSEG 的值
PRESDIV 為 CAN_CTRL1.PRESDIV 的值
上述公式也適用于 CAN 位時序寄存器(CAN_CBT)所述的 CAN 位時間變量。
因此,F(xiàn)lexCAN FD仲裁段使用經(jīng)典CAN位的速率計算公式為:
FlexCAN FD可變速率數(shù)據(jù)段的計算公式為:
fCANCLK為PE時鐘,單位Hz
BITRATEN是由CAN 標(biāo)稱位時間變量計算出的 CAN 位速率,單位bps
BITRATEF是由CAN 數(shù)據(jù)位時間變量計算出的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幀標(biāo)稱比特率相應(yīng)的每個CAN位的外設(shè)時鐘數(shù)量CPCBN為:
CAN FD 幀數(shù)據(jù)比特率相應(yīng)的每個CAN位的外設(shè)時鐘數(shù)量CPCBF為:
因此在已知FlexCAN FD時鐘和預(yù)分頻系數(shù)以及波特率的情況下可以計算出FlexCAN FD的標(biāo)稱位時間TqN總數(shù)和可變速率數(shù)據(jù)位時間TqF總數(shù),計算公式分別如下所示:
fcanclk / BITRATEN x (EPRESDIV+1) = [1+(EPSEG1+1)+(EPSEG2+1)+(EPROPSEG+1)]
fcanclk / BITRATEF x (FPRESDIV+1) = [1+(FPSEG1+1)+(FPSEG2+1)+FPROPSEG]
根據(jù)以上FlexCAN FD的位時序可知可以分別根據(jù)標(biāo)稱位時間TqN總數(shù)和可變速率數(shù)據(jù)位時間TqF總數(shù)分別計算出其標(biāo)稱位時間的采樣點和可變速率數(shù)據(jù)位時間的采樣點,即FlexCAN FD標(biāo)稱位時間的采樣點的計算公式為:
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位時間采樣點的計算
根據(jù)以上4章節(jié)FlexCAN的位時間描述以及FlexCAN FD位時間和采樣點的計算公式推導(dǎo),在給定FlexCAN FD時鐘和波特率以及分頻系數(shù)的情況下,可以使用FlexCAN的庫函數(shù)通過循環(huán)遍歷的方式實現(xiàn)自動計算FlexCAN FD的位時間的采樣點。
FlexCAN FD庫函數(shù)定義的協(xié)議時序代碼如下所示:
typedefstruct_flexcan_timing_config{ u16preDivider;/*!
FlexCAN FD標(biāo)稱位時間采樣點和可變速率采樣點的位時間的計算,可以通過循環(huán)遍歷方式實現(xiàn)自動計算,代碼如下所示:
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位時間采樣點應(yīng)用舉例,本文示例以MM32F0160的FlexCAN FD外設(shè)為例,其中FlexCAN FD的標(biāo)稱波特率為500K,可變速率波特率為2MHz。fCAN的時鐘為72MHz,把FlexCAN FD的fCAN時鐘,標(biāo)稱波特率500K,可變速率波特率2MHz代入庫函數(shù)FLEXCAN_FDCalculateImprovedTimingValues分別計算得出FlexCAN FD標(biāo)稱波特率和可變速率波特率的位時間參數(shù)如下:
標(biāo)稱波特率的位時間參數(shù):
preDivider = 0x01;
propSeg = 0x34;
phaseSeg1 = 0x08;
phaseSeg2 = 0x08;
rJumpwidth = 0x0E
可變速率波特率位時間參數(shù):
fpreDivider = 0x01;
fpropSeg = 0x07;
fphaseSeg1 = 0x04;
fphaseSeg2 = 0x04;
frJumpwidth = 0x03
注:再同步參數(shù)rJumpwidth 和frJumpwidth不參與FlexCANFD采樣點的計算
又因為在已知FlexCAN FD時鐘和預(yù)分頻系數(shù),以及波特率的情況下可以計算出FlexCAN FD的標(biāo)稱位時間TqN總數(shù)和可變速率數(shù)據(jù)位時間TqF總數(shù),計算公式分別如下所示:
標(biāo)稱位時間TqN總數(shù):
fcanclk / BITRATEN x (EPRESDIV+1) = [1+(EPSEG1+1)+(EPSEG2+1)+(EPROPSEG+1)]
代入自動計算得出的標(biāo)稱波特率500K的位時間參數(shù),計算出TqN:
TqN = 72000000/500000x(1+1)= 72
可變速率數(shù)據(jù)位時間TqF總數(shù):
fcanclk / BITRATEF x (FPRESDIV+1) = [1+(FPSEG1+1)+(FPSEG2+1)+FPROPSEG]
代入自動計算得出的可變波特率2MHz的位時間參數(shù),計算出TqF:
TqF = 72000000/2000000x(1+1)= 18
根據(jù)以上FlexCAN FD使用庫自動計算出的位時間參數(shù),以及標(biāo)稱位時間TqN總數(shù)和可變速率位時間TqF總數(shù),可以分別計算出其標(biāo)稱位時間的采樣點和可變速率數(shù)據(jù)位時間的采樣點,即FlexCAN FD標(biāo)稱位時間的采樣點的計算公式為:
FlexCAN_samplepoint = (SYNC_SEG+(EPROPSEG+1) +(EPSEG1+1) )/ (SYNC_SEG+(EPROPSEG+1) +(EPSEG1+1)+ (EPSEG2+1))
代入標(biāo)稱波特率500K的位時間參數(shù)計算標(biāo)稱波特率的位時間的采樣點如下:
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波特率的位時間參數(shù)計算可變速率的位時間的采樣點如下:
FlexCAN_FDsamplepoint = (1+7+(4+1))/(1+7+(4+1)+(4+1))= 72%
CAN采樣點一般設(shè)置在75%—80%之間,具體要根據(jù)CAN通信波特率大小配置。當(dāng)波特率不超過500K時,建議采樣點設(shè)置在87.5%;當(dāng)波特率大小在500K—800K之間的時候,建議采樣點設(shè)置在80%;當(dāng)波特率大于800K的時候,建議采樣點設(shè)置在75%。以上建議并不是絕對的,需根據(jù)應(yīng)用環(huán)境復(fù)雜程度通過調(diào)整FlexCAN FD的再同步參數(shù)rJumpwidth和frJumpwidth使得phaseSeg1和phaseSeg2以及fphaseSeg1和fphaseSeg2在標(biāo)稱波特率和可變波特率的位時間上前移或后移N(0-15)個Tq值來微調(diào)采樣點(雖然rJumpwidth和frJumpwidth不參與采樣點計算)。
注意事項:
關(guān)于采樣點的配置的一些額外建議:當(dāng)用戶在實際車用環(huán)境中出現(xiàn)FlexCAN無正常收發(fā)數(shù)據(jù)時除了根據(jù)錯誤標(biāo)志查找問題定位問題外,還可使用專業(yè)的CAN診斷儀測試出多節(jié)點總線上的rJumpwidth和frJumpwidth,phaseSeg1和phaseSeg2以及fphaseSeg1和fphaseSeg2參數(shù),參考這些位時間參數(shù)值來調(diào)整適配rJumpwidth和frJumpwidth,phaseSeg1和phaseSeg2以及fphaseSeg1和fphaseSeg2參數(shù)到CAN通信的合適的采樣點。
審核編輯:劉清
-
緩沖器
+關(guān)注
關(guān)注
6文章
1921瀏覽量
45473 -
CAN
+關(guān)注
關(guān)注
57文章
2744瀏覽量
463612 -
接收機(jī)
+關(guān)注
關(guān)注
8文章
1180瀏覽量
53453 -
FIFO芯片
+關(guān)注
關(guān)注
0文章
10瀏覽量
8803
原文標(biāo)題:靈動微課堂 (第277講)|MM32F0160的FlexCAN FD位時間采樣點的計算
文章出處:【微信號:MindMotion-MMCU,微信公眾號:靈動MM32MCU】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論