據(jù)幀結(jié)構(gòu)詳解:從比特流到工程實(shí)踐)
1. 從“線”到“幀”理解CAN通信的核心單元如果你接觸過(guò)汽車電子、工業(yè)控制或者機(jī)器人那么“CAN總線”這個(gè)詞大概率不會(huì)陌生。它就像這些復(fù)雜系統(tǒng)里的“神經(jīng)系統(tǒng)”負(fù)責(zé)在各個(gè)獨(dú)立的控制器ECU之間傳遞信息。但很多人包括一些剛?cè)胄械墓こ處煶3?huì)把“CAN總線”和“CAN通信”混為一談或者只知道有這么個(gè)東西在“傳數(shù)據(jù)”卻說(shuō)不清數(shù)據(jù)到底是怎么“包裝”和“運(yùn)輸”的。這就好比你知道快遞網(wǎng)絡(luò)很發(fā)達(dá)但不知道快遞單怎么寫(xiě)、包裹怎么封裝一旦出了問(wèn)題你連查都不知道從哪查起。實(shí)際上CAN總線是一套完整的通信“交通規(guī)則”和“公路設(shè)施”而數(shù)據(jù)幀Data Frame就是在這條公路上跑的一輛輛“標(biāo)準(zhǔn)貨車”。這輛貨車的結(jié)構(gòu)、載貨量、優(yōu)先級(jí)、甚至它自身的“身份證”ID都有一套嚴(yán)格的規(guī)定。理解數(shù)據(jù)幀是理解CAN通信如何工作的基石。無(wú)論是用TSMaster、CANalyzer這類軟件進(jìn)行測(cè)試還是用STM32、S7-200 SMART PLC進(jìn)行開(kāi)發(fā)抑或是解析充電樁的CAN報(bào)文你最終打交道的就是這一幀一幀的數(shù)據(jù)。網(wǎng)絡(luò)上搜索“can數(shù)據(jù)幀結(jié)構(gòu)”、“can報(bào)文”、“完整can報(bào)文的組成”的熱度恰恰說(shuō)明了這是大家實(shí)踐中最常遇到、也最需要厘清的基礎(chǔ)。所以今天我們不空談協(xié)議就扎扎實(shí)實(shí)地把這輛“標(biāo)準(zhǔn)貨車”——CAN數(shù)據(jù)幀——拆開(kāi)來(lái)看。從它的誕生背景、到每一部分的構(gòu)成、再到兩種主要形態(tài)標(biāo)準(zhǔn)幀與擴(kuò)展幀的區(qū)別最后聊聊在實(shí)際操作中你怎么去“看懂”和“構(gòu)造”一幀數(shù)據(jù)。無(wú)論你是正在調(diào)試ESP32-C3的USB轉(zhuǎn)CAN還是苦惱于1200 PLC的OPC通信底層亦或是想弄明白Binder通信機(jī)制與CAN的異同這篇文章都會(huì)給你一個(gè)清晰、可直接操作的視角。2. CAN數(shù)據(jù)幀的誕生為什么是它在深入結(jié)構(gòu)之前我們得先明白為什么CAN協(xié)議要設(shè)計(jì)出“數(shù)據(jù)幀”這種形式。這得回到它的應(yīng)用場(chǎng)景高可靠性的分布式實(shí)時(shí)控制系統(tǒng)。想象一下一輛汽車的內(nèi)部發(fā)動(dòng)機(jī)控制器、變速箱控制器、ABS控制器、儀表盤(pán)等等它們需要持續(xù)不斷地交換速度、轉(zhuǎn)速、溫度、剎車信號(hào)等信息。這些信息交換有幾個(gè)核心需求多主競(jìng)爭(zhēng)與仲裁任何一個(gè)節(jié)點(diǎn)都可以在總線空閑時(shí)主動(dòng)發(fā)送數(shù)據(jù)。如果兩個(gè)節(jié)點(diǎn)同時(shí)發(fā)送就需要一個(gè)非破壞性的仲裁機(jī)制來(lái)決定誰(shuí)先說(shuō)誰(shuí)后說(shuō)。這個(gè)仲裁不能導(dǎo)致數(shù)據(jù)沖突或丟失。高實(shí)時(shí)性與優(yōu)先級(jí)剎車信號(hào)的優(yōu)先級(jí)必然高于空調(diào)調(diào)節(jié)信號(hào)。通信機(jī)制必須能區(qū)分優(yōu)先級(jí)讓重要的信息先走。強(qiáng)大的錯(cuò)誤檢測(cè)與處理在電磁環(huán)境復(fù)雜的汽車或工廠里通信必須極其可靠。任何傳輸錯(cuò)誤都需要能被發(fā)現(xiàn)并且系統(tǒng)能自動(dòng)恢復(fù)。廣播與過(guò)濾一個(gè)節(jié)點(diǎn)發(fā)出的數(shù)據(jù)理論上總線上所有其他節(jié)點(diǎn)都能收到。但每個(gè)節(jié)點(diǎn)通常只關(guān)心特定信息因此需要一個(gè)高效的過(guò)濾機(jī)制讓節(jié)點(diǎn)只處理它需要的“貨車”。CAN數(shù)據(jù)幀的設(shè)計(jì)完美地回應(yīng)了這些需求。它的結(jié)構(gòu)不是隨意定的每一段比特都有其明確的使命。整個(gè)幀以“幀起始”為號(hào)角以“幀結(jié)束”為終止中間包裹著仲裁場(chǎng)、控制場(chǎng)、數(shù)據(jù)場(chǎng)和CRC場(chǎng)等關(guān)鍵部分。這種結(jié)構(gòu)確保了在實(shí)現(xiàn)上述復(fù)雜功能的同時(shí)保持了極高的通信效率。相比之下你搜索中提到的UART、SPI、I2C等點(diǎn)對(duì)點(diǎn)或主從式通信在應(yīng)對(duì)這種多節(jié)點(diǎn)、廣播、帶仲裁的場(chǎng)景時(shí)就顯得力不從心了它們沒(méi)有內(nèi)嵌如此復(fù)雜的“交通管理”邏輯。3. 拆解“標(biāo)準(zhǔn)貨車”CAN數(shù)據(jù)幀的比特級(jí)結(jié)構(gòu)現(xiàn)在我們來(lái)把這輛“貨車”大卸八塊。一個(gè)完整的CAN數(shù)據(jù)幀這里指最常用的“數(shù)據(jù)幀”區(qū)別于遠(yuǎn)程幀、錯(cuò)誤幀、過(guò)載幀由以下字段順序構(gòu)成。為了直觀我們假設(shè)一個(gè)標(biāo)準(zhǔn)幀數(shù)據(jù)長(zhǎng)度為8字節(jié)。3.1 幀起始Start of Frame, SOF這是一個(gè)單獨(dú)的“顯性”比特邏輯0。它就像起跑線上的發(fā)令槍告訴總線上所有節(jié)點(diǎn)“注意有一幀數(shù)據(jù)要開(kāi)始發(fā)送了”所有節(jié)點(diǎn)都利用這個(gè)下降沿來(lái)同步自己的時(shí)鐘。這個(gè)比特必須是顯性的這保證了總線空閑隱性電平邏輯1狀態(tài)的唯一性被打破從而標(biāo)志傳輸開(kāi)始。3.2 仲裁場(chǎng)Arbitration Field這是CAN總線最精妙的部分之一它同時(shí)解決了兩個(gè)問(wèn)題報(bào)文標(biāo)識(shí)ID和總線仲裁。標(biāo)識(shí)符Identifier在標(biāo)準(zhǔn)幀中這里是11個(gè)比特在擴(kuò)展幀中是29個(gè)比特11位基礎(chǔ)ID 18位擴(kuò)展ID。這個(gè)ID不僅代表了這幀數(shù)據(jù)的內(nèi)容比如“發(fā)動(dòng)機(jī)轉(zhuǎn)速”更關(guān)鍵的是它的二進(jìn)制值決定了報(bào)文的優(yōu)先級(jí)。數(shù)值越小優(yōu)先級(jí)越高。因?yàn)橹俨脮r(shí)節(jié)點(diǎn)一邊發(fā)送一邊回讀總線電平。如果它發(fā)送的是隱性1但讀到的是顯性0它就意識(shí)到有更高優(yōu)先級(jí)的節(jié)點(diǎn)在發(fā)送于是立即退出發(fā)送轉(zhuǎn)為接收模式。這個(gè)過(guò)程是逐位進(jìn)行的不會(huì)破壞高優(yōu)先級(jí)報(bào)文的發(fā)送。遠(yuǎn)程傳輸請(qǐng)求位RTR, Remote Transmission Request在數(shù)據(jù)幀中這個(gè)比特位必須是“顯性”0以示“我這是一個(gè)數(shù)據(jù)幀我?guī)е鴶?shù)據(jù)來(lái)了”。如果是“隱性”1則表示這是一個(gè)“遠(yuǎn)程幀”用于請(qǐng)求另一個(gè)節(jié)點(diǎn)發(fā)送具有相同ID的數(shù)據(jù)幀。這就是為什么你搜索“can能又收又發(fā)嗎”——當(dāng)然可以任何一個(gè)節(jié)點(diǎn)都可以主動(dòng)發(fā)送數(shù)據(jù)幀也可以發(fā)送遠(yuǎn)程幀去“要”數(shù)據(jù)。3.3 控制場(chǎng)Control Field控制場(chǎng)共6個(gè)比特包含兩個(gè)保留位和一個(gè)至關(guān)重要的數(shù)據(jù)長(zhǎng)度碼DLC, Data Length Code。保留位r0, r1必須發(fā)送為顯性0接收方可以忽略。它們?yōu)槲磥?lái)協(xié)議擴(kuò)展預(yù)留。數(shù)據(jù)長(zhǎng)度碼DLC, 4 bits這4個(gè)比特編碼了后面數(shù)據(jù)場(chǎng)中包含的數(shù)據(jù)字節(jié)數(shù)。這里有一個(gè)非常重要的細(xì)節(jié)DLC的編碼范圍是0-8表示CAN數(shù)據(jù)幀最多可以攜帶8個(gè)字節(jié)的應(yīng)用數(shù)據(jù)。這是CAN協(xié)議2.0A/B的規(guī)定。雖然有些廠商或更高層協(xié)議如CAN FD會(huì)借用DLC值9-15來(lái)表示其他含義如更大的數(shù)據(jù)包但在經(jīng)典CAN幀中DLC大于8的值必須被解釋為8。很多初學(xué)者在解析報(bào)文時(shí)看到DLC12就以為有12個(gè)數(shù)據(jù)字節(jié)這是錯(cuò)誤的實(shí)際上它只代表8個(gè)字節(jié)。3.4 數(shù)據(jù)場(chǎng)Data Field這就是貨車的“貨廂”里面裝著實(shí)際要傳輸?shù)膽?yīng)用數(shù)據(jù)。長(zhǎng)度由DLC指定為0-8個(gè)字節(jié)。數(shù)據(jù)是按字節(jié)順序發(fā)送的每個(gè)字節(jié)內(nèi)的最高位MSB先發(fā)送。這部分內(nèi)容是完全由用戶定義的協(xié)議不做解釋。比如前兩個(gè)字節(jié)可能表示一個(gè)16位的溫度值第三個(gè)字節(jié)可能表示狀態(tài)標(biāo)志位。你搜索“充電報(bào)文CAN協(xié)議解析工具”其核心工作之一就是根據(jù)預(yù)先定義好的數(shù)據(jù)庫(kù)DBC文件將這0-8個(gè)字節(jié)的原始數(shù)據(jù)解析成有物理意義的信號(hào)如電壓、電流、SOC。3.5 循環(huán)冗余校驗(yàn)場(chǎng)CRC Field為了保證數(shù)據(jù)傳輸?shù)臉O高可靠性CAN引入了CRC校驗(yàn)。CRC序列CRC Sequence, 15 bits發(fā)送節(jié)點(diǎn)根據(jù)幀起始、仲裁場(chǎng)、控制場(chǎng)、數(shù)據(jù)場(chǎng)的內(nèi)容計(jì)算出一個(gè)15位的CRC校驗(yàn)碼并附在數(shù)據(jù)場(chǎng)之后。CRC界定符CRC Delimiter這是一個(gè)單獨(dú)的“隱性”比特1。它用來(lái)隔開(kāi)CRC序列和后面的ACK場(chǎng)。這個(gè)比特必須是隱性的如果監(jiān)聽(tīng)到是顯性則說(shuō)明幀格式錯(cuò)誤。3.6 應(yīng)答場(chǎng)ACK Field這是一個(gè)體現(xiàn)CAN總線“廣播與確認(rèn)”機(jī)制的字段共2個(gè)比特。應(yīng)答間隙ACK Slot發(fā)送節(jié)點(diǎn)在這一位發(fā)送一個(gè)“隱性”1。而總線上所有正確接收到該幀即通過(guò)CRC校驗(yàn)的節(jié)點(diǎn)無(wú)論該幀ID是否與自身匹配都會(huì)在這一比特位時(shí)間段內(nèi)向總線發(fā)送一個(gè)“顯性”0電平覆蓋掉原來(lái)的隱性。所以發(fā)送節(jié)點(diǎn)回讀時(shí)如果讀到的是顯性0就知道至少有一個(gè)節(jié)點(diǎn)正確收到了。應(yīng)答界定符ACK Delimiter這是一個(gè)隱性比特1。發(fā)送節(jié)點(diǎn)必須在此檢測(cè)到隱性電平否則視為格式錯(cuò)誤。注意這里和很多人的直覺(jué)不同。ACK不是由目標(biāo)節(jié)點(diǎn)發(fā)出的而是由所有正確接收的節(jié)點(diǎn)發(fā)出的。這保證了只要總線有正常工作的節(jié)點(diǎn)發(fā)送方就能得到確認(rèn)增強(qiáng)了可靠性。3.7 幀結(jié)束End of Frame, EOF由7個(gè)連續(xù)的隱性比特1組成。這標(biāo)志著本幀數(shù)據(jù)的徹底結(jié)束總線恢復(fù)空閑狀態(tài)等待下一次幀起始。4. 標(biāo)準(zhǔn)幀 vs. 擴(kuò)展幀不僅僅是ID長(zhǎng)度不同在搜索熱詞里“擴(kuò)展幀”被單獨(dú)提及說(shuō)明這是一個(gè)常見(jiàn)的困惑點(diǎn)。它們的核心區(qū)別確實(shí)在仲裁場(chǎng)的ID長(zhǎng)度但影響遠(yuǎn)不止于此。標(biāo)準(zhǔn)幀CAN 2.0A使用11位標(biāo)識(shí)符。理論上可以提供2048個(gè)不同的報(bào)文ID。其仲裁場(chǎng)結(jié)構(gòu)為11位ID RTR位 IDE位 保留位r0。其中IDE位Identifier Extension在控制場(chǎng)對(duì)于標(biāo)準(zhǔn)幀IDE位為“顯性”0。擴(kuò)展幀CAN 2.0B使用29位標(biāo)識(shí)符11位基礎(chǔ)ID 18位擴(kuò)展ID。可以提供超過(guò)5億個(gè)不同的報(bào)文ID極大地?cái)U(kuò)展了尋址空間。其仲裁場(chǎng)結(jié)構(gòu)為11位基礎(chǔ)ID SRR位 IDE位 18位擴(kuò)展ID RTR位。SRR位Substitute Remote Request這是一個(gè)“隱性”1位它的位置對(duì)應(yīng)標(biāo)準(zhǔn)幀的RTR位。在仲裁時(shí)如果標(biāo)準(zhǔn)幀和擴(kuò)展幀發(fā)生沖突由于SRR是隱性而標(biāo)準(zhǔn)幀在相同位置是RTR數(shù)據(jù)幀為顯性0因此標(biāo)準(zhǔn)幀總是贏得仲裁。這是一個(gè)重要的兼容性設(shè)計(jì)。IDE位對(duì)于擴(kuò)展幀IDE位在仲裁場(chǎng)中且為“隱性”1。在實(shí)際操作中的選擇與避坑網(wǎng)絡(luò)兼容性一個(gè)CAN網(wǎng)絡(luò)中所有節(jié)點(diǎn)的幀格式必須兼容。如果一個(gè)節(jié)點(diǎn)配置為只接收標(biāo)準(zhǔn)幀有時(shí)稱為“2.0A主動(dòng)”它將無(wú)法處理擴(kuò)展幀甚至可能報(bào)錯(cuò)。現(xiàn)代控制器通常都支持“2.0B被動(dòng)”或“2.0B主動(dòng)”可以同時(shí)處理兩種格式。過(guò)濾配置這是最易出錯(cuò)的地方。當(dāng)你在STM32或類似MCU上配置CAN接收過(guò)濾器時(shí)必須明確知道你要接收的是標(biāo)準(zhǔn)幀還是擴(kuò)展幀并據(jù)此設(shè)置過(guò)濾器的模式標(biāo)識(shí)符列表模式或掩碼模式。如果你用標(biāo)準(zhǔn)幀的過(guò)濾器去匹配擴(kuò)展幀的ID是絕對(duì)收不到數(shù)據(jù)的。很多人在調(diào)試時(shí)發(fā)現(xiàn)“能發(fā)不能收”問(wèn)題就出在這里。工具軟件設(shè)置在使用TSMaster、CANalyzer等工具收發(fā)數(shù)據(jù)時(shí)創(chuàng)建或發(fā)送報(bào)文時(shí)必須正確選擇幀類型。如果你從設(shè)備捕獲到一個(gè)29位的ID但在軟件里以標(biāo)準(zhǔn)幀格式去解析或發(fā)送結(jié)果肯定是錯(cuò)誤的。5. 實(shí)操如何“看懂”和“構(gòu)造”一幀CAN數(shù)據(jù)理論說(shuō)再多不如動(dòng)手看一看。我們結(jié)合常見(jiàn)的工具和場(chǎng)景來(lái)講解。5.1 解析一幀真實(shí)的CAN數(shù)據(jù)假設(shè)我們?cè)赥SMaster上捕獲到如下一幀數(shù)據(jù)十六進(jìn)制表示ID: 0x123Data: 01 23 45 67 89 AB CD EFDLC: 8確定幀類型ID0x123是11位ID因?yàn)?x123 291小于0x7FF所以這是一個(gè)標(biāo)準(zhǔn)數(shù)據(jù)幀。分析仲裁場(chǎng)ID二進(jìn)制001 0010 0011。這個(gè)值決定了它的優(yōu)先級(jí)。RTR位因?yàn)槭菙?shù)據(jù)幀所以是顯性0。在總線上這個(gè)字段實(shí)際發(fā)送的比特流是ID(11位) RTR(0)。注意ID的最高位先發(fā)送。分析控制場(chǎng)IDE位標(biāo)準(zhǔn)幀顯性0。保留位r0顯性0。DLC8的二進(jìn)制是1000表示數(shù)據(jù)場(chǎng)有8個(gè)字節(jié)。所以控制場(chǎng)發(fā)送的比特流是IDE(0) r0(0) DLC(1000)。分析數(shù)據(jù)場(chǎng)就是連續(xù)的8個(gè)字節(jié)0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF。每個(gè)字節(jié)的最高位先發(fā)送。后續(xù)字段CRC、ACK、EOF由硬件自動(dòng)處理在軟件層面通常不直接顯示原始比特但軟件會(huì)利用CRC和ACK的結(jié)果來(lái)標(biāo)記該幀是否有效。如果這幀數(shù)據(jù)來(lái)自一個(gè)汽車ECU并且你加載了對(duì)應(yīng)的DBC文件TSMaster可能會(huì)自動(dòng)將其解析為EngineSpeed: 2150 RPM,CoolantTemp: 85 °C等有物理意義的信號(hào)。這就是“解析工具”干的事情——將原始的8字節(jié)數(shù)據(jù)按照DBC中定義的布局起始位、長(zhǎng)度、精度、偏移量進(jìn)行解包和換算。5.2 在代碼中構(gòu)造并發(fā)送一幀數(shù)據(jù)以STM32的HAL庫(kù)為例發(fā)送上述數(shù)據(jù)幀的代碼邏輯如下CAN_TxHeaderTypeDef TxHeader; uint8_t TxData[8]; uint32_t TxMailbox; // 1. 配置幀頭 TxHeader.StdId 0x123; // 使用標(biāo)準(zhǔn)ID TxHeader.ExtId 0x0000; // 擴(kuò)展ID未使用 TxHeader.IDE CAN_ID_STD; // 幀類型標(biāo)準(zhǔn)幀 TxHeader.RTR CAN_RTR_DATA; // 幀格式數(shù)據(jù)幀 TxHeader.DLC 8; // 數(shù)據(jù)長(zhǎng)度8字節(jié) TxHeader.TransmitGlobalTime DISABLE; // 2. 填充數(shù)據(jù) TxData[0] 0x01; TxData[1] 0x23; TxData[2] 0x45; TxData[3] 0x67; TxData[4] 0x89; TxData[5] 0xAB; TxData[6] 0xCD; TxData[7] 0xEF; // 3. 啟動(dòng)發(fā)送 if (HAL_CAN_AddTxMessage(hcan1, TxHeader, TxData, TxMailbox) ! HAL_OK) { // 錯(cuò)誤處理 }關(guān)鍵點(diǎn)TxHeader這個(gè)結(jié)構(gòu)體就是你為這輛“貨車”填寫(xiě)的“運(yùn)單”明確指明了它的ID、類型、長(zhǎng)度。而TxData數(shù)組就是裝載的貨物??刂破饔布?huì)根據(jù)這個(gè)“運(yùn)單”自動(dòng)生成符合CAN協(xié)議規(guī)范的比特流包括自動(dòng)計(jì)算CRC、處理ACK等。5.3 常見(jiàn)問(wèn)題與排查思路結(jié)合搜索熱詞中反映的困惑這里有幾個(gè)典型問(wèn)題“為什么我發(fā)的數(shù)據(jù)對(duì)方收不到”波特率這是第一道坎。發(fā)送和接收節(jié)點(diǎn)的波特率如125kbps, 500kbps, 1Mbps必須嚴(yán)格一致差一點(diǎn)都不行。幀格式確認(rèn)雙方是標(biāo)準(zhǔn)幀還是擴(kuò)展幀。用標(biāo)準(zhǔn)幀發(fā)用擴(kuò)展幀收肯定收不到。過(guò)濾器配置接收方必須配置了正確的過(guò)濾器允許你發(fā)送的ID通過(guò)。如果過(guò)濾器設(shè)置過(guò)窄或完全關(guān)閉報(bào)文會(huì)被硬件直接丟棄軟件層根本看不到。物理層檢查終端電阻通常120歐姆掛在總線兩端、線纜連接、共地。可以用示波器或CAN總線分析儀查看波形是否正常。“DLC明明設(shè)了8怎么數(shù)據(jù)看起來(lái)不對(duì)”檢查你的數(shù)據(jù)填充代碼。確保數(shù)組索引正確數(shù)據(jù)在內(nèi)存中的值符合預(yù)期。另外如前所述在經(jīng)典CAN中DLC大于8也只會(huì)發(fā)送8個(gè)字節(jié)?!叭绾谓馕鱿癯潆妶?bào)文那樣的復(fù)雜數(shù)據(jù)”這超出了單幀的范疇進(jìn)入了高層協(xié)議如CANopen, J1939, 或廠商自定義協(xié)議的領(lǐng)域。你需要對(duì)應(yīng)的協(xié)議文檔和DBC文件。DBC文件定義了哪個(gè)ID對(duì)應(yīng)哪個(gè)報(bào)文以及該報(bào)文的8個(gè)字節(jié)如何分割成幾十個(gè)甚至上百個(gè)獨(dú)立的信號(hào)Signal每個(gè)信號(hào)有起始位、長(zhǎng)度、字節(jié)序Intel/Motorola、精度、偏移量、單位等。使用CANalyst、PCAN-View或Vector的工具鏈加載DBC后才能實(shí)現(xiàn)自動(dòng)解析。自己寫(xiě)解析代碼就是按照DBC的定義從8字節(jié)數(shù)組中按位提取、轉(zhuǎn)換。理解CAN數(shù)據(jù)幀就像拿到了CAN總線世界的“語(yǔ)法手冊(cè)”。它是一切應(yīng)用的基礎(chǔ)。無(wú)論是調(diào)試S7-200 SMART的TCP通信轉(zhuǎn)CAN還是研究Linux下的多進(jìn)程通信框架與CAN的類比抑或是解決那些令人頭疼的“UnicodeDecodeError”或“can‘t connect to target”背后可能存在的通信配置問(wèn)題對(duì)數(shù)據(jù)幀的深刻理解都能幫你更快地定位到問(wèn)題的本質(zhì)。下次當(dāng)你再看到一串CAN報(bào)文時(shí)希望你能在腦海里清晰地浮現(xiàn)出它從SOF到EOF的完整比特流畫(huà)卷以及每一段比特所承載的職責(zé)。這才是真正駕馭CAN通信的開(kāi)始。