CAN總線簡(jiǎn)易入門(mén)教程
目錄
- 什么是CAN總線?
- 物理層
- 差分信號(hào)
- 連接方式
- CAN節(jié)點(diǎn)
- CAN協(xié)議
- 如何尋址?
- 幀類(lèi)型
- 數(shù)據(jù)幀
- 遠(yuǎn)程幀
- 錯(cuò)誤幀
- 過(guò)載幀
- 消息時(shí)序以及同步
- 位時(shí)序
- 波特率
- 消息過(guò)濾器
- 如何配置?
- 總結(jié)
- 參考
什么是CAN總線?
Controller Area Network,簡(jiǎn)稱(chēng)CAN或者CAN bus) 是一種功能豐富的串行總線標(biāo)準(zhǔn),最早的CAN控制芯片在奔馳車(chē)上應(yīng)用并量產(chǎn),因?yàn)橹С侄嘀鳈C(jī),多從機(jī)的優(yōu)點(diǎn),所以一輛車(chē)所有控制器,傳感器,電子設(shè)備直接的通信只需要兩條線就夠了,大大優(yōu)化了整車(chē)的布線。[^wiki can bus]隨著技術(shù)的不斷發(fā)展,CAN發(fā)布了相應(yīng)的標(biāo)準(zhǔn),國(guó)際化標(biāo)準(zhǔn)組織,公布了CAN的不同標(biāo)準(zhǔn);標(biāo)準(zhǔn) | 涵蓋內(nèi)容 |
---|---|
ISO 11898-1 | 數(shù)據(jù)鏈路層 |
ISO 11898-2 | 高速CAN的物理層 |
ISO 11898-3 | 低速容錯(cuò)CAN的物理層 |
ISO 11898-1
?,ISO 11898-2
是對(duì)應(yīng)的設(shè)計(jì)標(biāo)準(zhǔn),去搜索就可以知道這個(gè)技術(shù)點(diǎn)是如何進(jìn)行設(shè)計(jì)的。
物理層
差分信號(hào)
這里我們介紹一下物理層,什么是物理層呢?就是CAN的電信號(hào)的傳輸過(guò)程。CAN是串行異步通訊,只有CAN_HIGH
和CAN_LOW
兩條差分信號(hào)線,數(shù)據(jù)通過(guò)差分信號(hào)的方式進(jìn)行通訊,其優(yōu)點(diǎn)就是可以增加信號(hào)的抗干擾能力,抑制共模信號(hào)的干擾;具體如下圖所示;連接方式
CAN總線支持多個(gè)節(jié)點(diǎn)掛載在總線上,比較類(lèi)似I2C
總線,可以在SCL
和SDA
上掛載多個(gè)從機(jī),具體如下圖所示;Node
),節(jié)點(diǎn)直接可以相互通訊,相較于I2C
總線,CAN總線設(shè)置了終端電阻,常見(jiàn)的一種閉環(huán)連接模式,相對(duì)的還有開(kāi)環(huán)的連接模式。不同的連接模式,他們的通訊速率也大不相同,這里也就是高速CAN和低速CAN的區(qū)別。兩條電線組成一條雙絞線,并且接有120Ω的特性阻抗。ISO 11898-2,也稱(chēng)為高速度CAN。它在總線的兩端均接有120Ω電阻。使用了
120Ω
終端電阻(這是CAN的ISO標(biāo)準(zhǔn)里規(guī)定的),這種模式的最高通訊速率可以達(dá)到1Mbps,下面是傳輸距離和傳輸速度的關(guān)系;1 Mbps
降低到 125 Kbps
,并且不再在總線的起點(diǎn)和終點(diǎn)使用兩個(gè)終端電阻,而是將電阻分布在每個(gè)節(jié)點(diǎn)上。具體如下圖所示;由于高速CAN和低速CAN的拓?fù)浣Y(jié)構(gòu)不同,另外終端電阻的分布也不同,所以CAN_HIGH
和CAN_LOW
上的電平是不相同的,這里有隱性電平和顯性電平。硬件上的連接基本上都搞清楚了,下面就是如何去實(shí)現(xiàn)一個(gè)具體的CAN節(jié)點(diǎn)。我們來(lái)簡(jiǎn)單地介紹一下。
CAN節(jié)點(diǎn)
CAN節(jié)點(diǎn)通常分為三個(gè)部分;- MCU/CPU;
- CAN控制器,
- CAN收發(fā)器;
STM32
,所以我們常見(jiàn)的結(jié)構(gòu)一般是這樣子的。- CAN總線上通過(guò)差分信號(hào)進(jìn)行數(shù)據(jù)傳輸;
- CAN收發(fā)器將差分信號(hào)轉(zhuǎn)換為T(mén)TL電平信號(hào),或者將TTL電平信號(hào)轉(zhuǎn)換為差分信號(hào);
- CAN控制器將TTL電平信號(hào)接收,并傳輸給MCU;
CAN協(xié)議
CAN協(xié)議和網(wǎng)絡(luò)協(xié)議比較類(lèi)似,進(jìn)行了分層的設(shè)計(jì)思想;- 物理層就是前面提到過(guò)的硬件拓?fù)浣Y(jié)構(gòu),包括高速CAN和低速CAN,而CAN收發(fā)器就屬于物理層;
- 傳輸層則是CAN控制器所需要做的事情,包括CAN時(shí)序,同步,消息仲裁,確認(rèn),錯(cuò)誤檢驗(yàn)等,這個(gè)比較復(fù)雜,如果只是應(yīng)用開(kāi)發(fā),我認(rèn)為,簡(jiǎn)單了解一下即可;這一層需要做的工作包括:
- 故障約束;
- 錯(cuò)誤監(jiān)測(cè);
- 消息驗(yàn)證;
- 信息確認(rèn);
- 仲裁;
- 信息幀;
- 傳輸速率和時(shí)間;
- 路由信息;
- 對(duì)象層,MCU應(yīng)該是屬于這一層,我們需要對(duì)CAN消息做信息的過(guò)濾設(shè)置,CAN消息的處理等等;
- 應(yīng)用層就是基于對(duì)象層的進(jìn)一步封裝,不同的CAN標(biāo)準(zhǔn),比如工業(yè)自動(dòng)化領(lǐng)域的
CANopen
,汽車(chē)診斷ISO 14229 定義的UDS等等;
如何尋址?
CAN總線上的每個(gè)節(jié)點(diǎn)不需要設(shè)置節(jié)點(diǎn)的地址,而是通過(guò)消息的標(biāo)識(shí)符(Identifier)來(lái)區(qū)別信息。因?yàn)镃AN總線的消息是廣播的(就是大家都可以收到消息),比如總線上有節(jié)點(diǎn)A,節(jié)點(diǎn)B,節(jié)點(diǎn)C,那么節(jié)點(diǎn)A發(fā)消息,節(jié)點(diǎn)B和節(jié)點(diǎn)C都會(huì)收到消息;節(jié)點(diǎn)B 和 節(jié)點(diǎn)C 會(huì)根據(jù)消息中的標(biāo)識(shí)符,以及B和C中的消息過(guò)濾規(guī)則進(jìn)行比較,如果不滿(mǎn)足規(guī)則,就不接受這條信息。這里需要注意的是:- 發(fā)送消息的時(shí)候,總線必須處于空閑狀態(tài);
- 標(biāo)識(shí)符越小,則消息獲取總線的優(yōu)先級(jí)越高;
幀類(lèi)型
CAN有4種幀類(lèi)型:- 數(shù)據(jù)幀:包含用于傳輸?shù)墓?jié)點(diǎn)數(shù)據(jù)的幀
- 遠(yuǎn)程幀:請(qǐng)求傳輸特定標(biāo)識(shí)符的幀
- 錯(cuò)誤幀:由任何檢測(cè)到錯(cuò)誤的節(jié)點(diǎn)發(fā)送的幀
- 過(guò)載幀:在數(shù)據(jù)幀或遠(yuǎn)程幀之間插入延遲的幀
數(shù)據(jù)幀
數(shù)據(jù)幀分為標(biāo)準(zhǔn)幀和擴(kuò)展幀兩種格式;- 基本幀格式:有11個(gè)標(biāo)識(shí)符位
- 擴(kuò)展幀格式:有29個(gè)標(biāo)識(shí)符位
sof
:start of frame
,表示數(shù)據(jù)幀開(kāi)始;(1 bit)Identifier
:標(biāo)準(zhǔn)格式11 bit,擴(kuò)展格式29 bit包括Base Identifier(11 bit)和Extended Identifier(18 bit),該區(qū)段標(biāo)識(shí)數(shù)據(jù)幀的優(yōu)先級(jí),數(shù)值越小,優(yōu)先級(jí)越高;RTR
:遠(yuǎn)程傳輸請(qǐng)求位,0時(shí)表示為數(shù)據(jù)幀,1表示為遠(yuǎn)程幀,也就是說(shuō)RTR=1時(shí),消息幀的Data Field為空;(1 bit)IDE
:標(biāo)識(shí)符擴(kuò)展位,0時(shí)表示為標(biāo)準(zhǔn)格式,1表示為擴(kuò)展格式;(1 bit)DLC
:數(shù)據(jù)長(zhǎng)度代碼,0~8表示數(shù)據(jù)長(zhǎng)度為0~8 Byte;(4 bit)Data Field
:數(shù)據(jù)域;(0~8 Byte)CRC Sequence
:校驗(yàn)域,校驗(yàn)算法,DEL
:校驗(yàn)域和應(yīng)答域的隱性界定符;(1 bit)ACK
:應(yīng)答,確認(rèn)數(shù)據(jù)是否正常接收,所謂正常接收是指不含填充錯(cuò)誤、格式錯(cuò)誤、 CRC 錯(cuò)誤。發(fā)送節(jié)點(diǎn)將此位為1,接收節(jié)點(diǎn)正常接收數(shù)據(jù)后將此位置為0;(1 bit)SRR
:替代遠(yuǎn)程請(qǐng)求位,在擴(kuò)展格式中占位用,必須為1;(1 bit)EOF
:連續(xù)7個(gè)隱性位(1)表示幀結(jié)束;(7 bit)ITM
:幀間空間,Intermission (ITM)
,又稱(chēng)Interframe Space
(IFS),連續(xù)3個(gè)隱性位,但它不屬于數(shù)據(jù)幀。幀間空間是用于將數(shù)據(jù)幀和遠(yuǎn)程幀與前面的幀分離開(kāi)來(lái)的幀。數(shù)據(jù)幀和遠(yuǎn)程幀可通過(guò)插入幀間空間將本幀與前面的任何幀(數(shù)據(jù)幀、遙控幀、錯(cuò)誤幀、過(guò)載幀)分開(kāi)。過(guò)載幀和錯(cuò)誤幀前不能插入幀間空間。
遠(yuǎn)程幀
一般地,數(shù)據(jù)是由發(fā)送單元主動(dòng)向總線上發(fā)送的,但也存在接收單元主動(dòng)向發(fā)送單元請(qǐng)求數(shù)據(jù)的情況。遠(yuǎn)程幀的作用就在于此,它是接收單元向發(fā)送單元請(qǐng)求發(fā)送數(shù)據(jù)的幀。遠(yuǎn)程幀與數(shù)據(jù)幀的幀結(jié)構(gòu)類(lèi)似,如上圖X所示。遠(yuǎn)程幀與數(shù)據(jù)幀的幀結(jié)構(gòu)區(qū)別有兩點(diǎn):- 數(shù)據(jù)幀的 RTR 值為“0”,遠(yuǎn)程幀的 RTR 值為“1”
- 遠(yuǎn)程幀沒(méi)有數(shù)據(jù)塊
錯(cuò)誤幀
用于在接收和發(fā)送消息時(shí)檢測(cè)出錯(cuò)誤時(shí),通知錯(cuò)誤的幀。錯(cuò)誤幀由錯(cuò)誤標(biāo)志和錯(cuò)誤界定符構(gòu)成。錯(cuò)誤幀的幀結(jié)構(gòu)如圖11示。- 錯(cuò)誤標(biāo)志:個(gè)顯性/隱性重疊位
- 主動(dòng)錯(cuò)誤標(biāo)志(6個(gè)顯性位):處于主動(dòng)錯(cuò)誤狀態(tài)的單元檢測(cè)出錯(cuò)誤時(shí)輸出的錯(cuò)誤標(biāo)志
- 被動(dòng)錯(cuò)誤標(biāo)志(6個(gè)隱性位):處于被動(dòng)錯(cuò)誤狀態(tài)的單元檢測(cè)出錯(cuò)誤時(shí)輸出的錯(cuò)誤標(biāo)志
- 錯(cuò)誤界定符:8 個(gè)隱性位
過(guò)載幀
過(guò)載幀是用于接收單元通知發(fā)送單元它尚未完成接收準(zhǔn)備的幀。在兩種情況下,節(jié)點(diǎn)會(huì)發(fā)送過(guò)載幀:- 接收單元條件的制約,要求發(fā)送節(jié)點(diǎn)延緩下一個(gè)數(shù)據(jù)幀或遠(yuǎn)程幀的傳輸;
- 幀間空間(Intermission)的 3 bit 內(nèi)檢測(cè)到顯性位
消息時(shí)序以及同步
位時(shí)序
在講CAN消息時(shí)序和同步之前,我們可以對(duì)照一下UART串口的傳輸協(xié)議,他有起始位和停止位,然后大家都規(guī)定使用相同的通訊速率(波特率);其實(shí)CAN通訊也是類(lèi)似的方式,它屬于異步通訊,沒(méi)有時(shí)鐘信號(hào)線,所以所有節(jié)點(diǎn)之間要約定好使用相同的波特率來(lái)傳輸數(shù)據(jù)。在總線空閑一段時(shí)間后,在(起始位) 進(jìn)行硬同步,同步方式是將每一位劃分成多個(gè)稱(chēng)為量子的時(shí)間段(time quanta),并分配一定數(shù)量的量子到位中的四個(gè)階段完成的。這四個(gè)階段分別為:SYNC_SEG
:同步段,1 個(gè)時(shí)間量子長(zhǎng)度。它用于同步各種總線節(jié)點(diǎn);PROP_SEG
:傳播段,1~8 時(shí)間量子長(zhǎng)度。它用于補(bǔ)償網(wǎng)絡(luò)上的信號(hào)延遲。PHASE_SEG_1
:相位緩沖段1,1~8 時(shí)間量子長(zhǎng)度。它用于補(bǔ)償邊緣相位誤差,在重新同步期間可能會(huì)延長(zhǎng)。PHASE_SEG_2
:相位緩沖段2,2~8 時(shí)間量子長(zhǎng)度。它用于補(bǔ)償邊緣相位誤差
波特率
如何計(jì)算波特率,需要知道每個(gè)量子時(shí)間的長(zhǎng)度(time quanta),以及每一位需要多少個(gè)量子時(shí)間,假設(shè)這里time quanta = 1us
,并且1 bit = 8 tq
,那么上圖中的波特率就應(yīng)該是:消息過(guò)濾器
前面有提到消息在CAN總線上是廣播式的,但并不是所有節(jié)點(diǎn)都會(huì)對(duì)總線上所有消息感興趣。節(jié)點(diǎn)通過(guò)控制器中過(guò)濾碼(Filter Code )和掩碼(Mask Code),再檢驗(yàn)總線上消息的標(biāo)識(shí)符,來(lái)判斷是否接收該消息(Message Filtering)。對(duì)于掩碼,“1”表示該位與本節(jié)點(diǎn)相關(guān),“0”表示該位與本節(jié)點(diǎn)不相關(guān)。舉例如下:例1:僅接收消息標(biāo)識(shí)符為00001567
(十六進(jìn)制)的幀- 設(shè)置過(guò)濾碼為
00001567
- 設(shè)置掩碼為
1FFFFFFF
00001567
接收,否則舍棄。例2:接收消息標(biāo)識(shí)符為00001567
到0000156F
的幀- 設(shè)置過(guò)濾碼為
00001560
- 設(shè)置掩碼為
1FFFFFF0
00001560
到 00001567
的幀- 設(shè)置過(guò)濾碼為
00001560
- 設(shè)置掩碼為
1FFFFFF8
- 設(shè)置過(guò)濾碼為
0
- 設(shè)置掩碼為
0
如何配置?
上面介紹了幀類(lèi)型,那么如何基于MCU
進(jìn)行配置呢?這里以STM32F407
為硬件平臺(tái),使用HAL庫(kù)進(jìn)行初始化,看一下都對(duì)哪些地方進(jìn)行了配置。一般來(lái)說(shuō),我們需要配置CAN的波特率,消息過(guò)濾器等等,下面是簡(jiǎn)單的配置的代碼;CAN_HandleTypeDef?hCAN;
void?MX_CAN_Init(void)
{
????CAN_FilterTypeDef???sFilterConfig;
????/*CAN單元初始化*/
????hCAN.Instance?=?CAN1;??????/*?CAN外設(shè)?*/
?
????/*?BTR-BRP?波特率分頻器??定義了時(shí)間單元的時(shí)間長(zhǎng)度42/(1 6 7)/6=500Kbps?*/
????hCAN.Init.Prescaler?=?6;
????hCAN.Init.Mode?=?CAN_MODE_NORMAL;???/*?正常工作模式?*/
????hCAN.Init.SyncJumpWidth?=?CAN_SJW_1TQ;??/*?BTR-SJW?重新同步跳躍寬度?1個(gè)時(shí)間單元?*/
????hCAN.Init.TimeSeg1?=?CAN_BS1_6TQ;???/*?BTR-TS1?時(shí)間段1?占用了6個(gè)時(shí)間單元?*/
????hCAN.Init.TimeSeg2?=?CAN_BS2_7TQ;???/*?BTR-TS1?時(shí)間段2?占用了7個(gè)時(shí)間單元?*/
????hCAN.Init.TimeTriggeredMode?=?DISABLE;??/*?MCR-TTCM??關(guān)閉時(shí)間觸發(fā)通信模式使能?*/?
????hCAN.Init.AutoBusOff?=?ENABLE;????/*?MCR-ABOM??自動(dòng)離線管理?*/
????hCAN.Init.AutoWakeUp?=?ENABLE;????/*?MCR-AWUM??使用自動(dòng)喚醒模式?*/
????hCAN.Init.AutoRetransmission?=?DISABLE;??/*?MCR-NART??禁止報(bào)文自動(dòng)重傳???DISABLE-自動(dòng)重傳?*/
????/*?MCR-RFLM??接收FIFO?鎖定模式??DISABLE-溢出時(shí)新報(bào)文會(huì)覆蓋原有報(bào)文?*/
????hCAN.Init.ReceiveFifoLocked?=?DISABLE;??
????/*?MCR-TXFP??發(fā)送FIFO優(yōu)先級(jí)?DISABLE-優(yōu)先級(jí)取決于報(bào)文標(biāo)示符?*/
????hCAN.Init.TransmitFifoPriority?=?DISABLE;?
????if?(HAL_CAN_Init(