最近看到有網(wǎng)友在技術(shù)群里討論關(guān)于“CAN比UART難不難”的話題,有人說CAN很簡單,但也有人說CAN很難。
其實(shí),難不難主要看你站在什么角度,有的網(wǎng)友可能基礎(chǔ)較好,又學(xué)習(xí)過CAN,可能就覺得簡單。但是,對(duì)于基礎(chǔ)較差的初學(xué)者來說,CAN確實(shí)相對(duì)UART難的多。
本文就針對(duì)初學(xué)者,分享一下CAN總線的一些基礎(chǔ),相對(duì)UART內(nèi)容確實(shí)要多很多。至于CAN相比UART難不難,你看了之后自己就有答案了。
一、CAN總線波特率
CAN總線屬于異步通信,因此就有通信波特率,而這個(gè)波特率發(fā)生器就位于CAN控制器內(nèi)部。我們不需要了解它是如何產(chǎn)生的,但需要了解它的含義。這章節(jié)針對(duì)初學(xué)者講述以下兩點(diǎn)內(nèi)容。
1、異步通信 ? 在串行通信中,主要分異步通信和同步通信。 ? 同步通信:通信設(shè)備之間通過同步信號(hào)(CLK時(shí)鐘)來實(shí)現(xiàn)數(shù)據(jù)傳輸?shù)耐ㄐ沤型酵ㄐ拧H?a href="http://www.nxhydt.com/tags/i2c/" target="_blank">I2C、SPI這類通信中都具有一個(gè)時(shí)鐘信號(hào),其實(shí)在STM32中USART也具有同步功能,只是我們大多數(shù)人都只用了它的異步功能。 ? 異步通信:簡單來說,就是通信設(shè)備之間通過約定一樣的時(shí)間來收發(fā)數(shù)據(jù)。而這個(gè)時(shí)間就會(huì)決定本節(jié)說的波特率。 ? 2、波特率 輕松看懂波特圖 如何用示波器測(cè)量串口波特率 ? 很多工程師一直都沒徹底搞明白什么是波特率,我這里還是結(jié)合UART波特率來簡述一下其含義。 ? 在電子通信領(lǐng)域,波特(Baud)即調(diào)制速率,指的是有效數(shù)據(jù)信號(hào)調(diào)制載波的速率,即單位時(shí)間內(nèi)載波調(diào)制狀態(tài)變化的次數(shù)。它是對(duì)符號(hào)傳輸速率的一種度量,1波特即指每秒傳輸1個(gè)符號(hào)。 ? UART每秒鐘傳送240個(gè)字符,而每個(gè)字符格式包含10位(1個(gè)起始位,1個(gè)停止位,8個(gè)數(shù)據(jù)位),這時(shí)的波特率為240Bd,比特率為10位*240個(gè)/秒=2400bps。 ?
從上面的描述可以總結(jié):
比特率:即單位時(shí)間內(nèi)傳送的二進(jìn)制位數(shù)
波特率:即單位時(shí)間內(nèi)傳輸?shù)姆?hào)個(gè)數(shù)
只有在每個(gè)符號(hào)只代表一個(gè)比特信息的情況下,波特率與比特率才在數(shù)值上相等,但是它們的意義并不相同。 ?
二、位時(shí)序
上面講述了波特率,而決定波特率大小的就是本節(jié)說的位時(shí)序。在CAN標(biāo)準(zhǔn)中一個(gè)位可分為4段:
同步段(SS)
傳播時(shí)間段(PTS)
相位緩沖段1(PBS1)
相位緩沖段2(PBS2)
這些段又由可稱為 Time Quantum(簡稱Tq)的最小時(shí)間單位構(gòu)成。 ? 1位分為4個(gè)段,每個(gè)段又由若干個(gè)Tq構(gòu)成,這稱為位時(shí)序。 ? 而在STM32參考手冊(cè)中,將位時(shí)序分為三段,但它將它傳播段和位段1合并在一起了,如下圖所示: ?
? 1位由多少個(gè)Tq構(gòu)成、每個(gè)段又由多少個(gè)Tq構(gòu)成等,可任意設(shè)定位時(shí)序。通過設(shè)定位時(shí)序,決定傳輸?shù)牟ㄌ芈剩??
? 這幾個(gè)參數(shù)會(huì)在以后編程中進(jìn)行配置,從而決定通信的波特率。 ? 關(guān)于同步,還有硬件同步、再同步等操作。但初學(xué)者可以不必過多理解,掌握上面基礎(chǔ)內(nèi)容就行了。更多關(guān)于位時(shí)序的內(nèi)容可以參看 ISO 11898 標(biāo)準(zhǔn)。 ?
三、幀類型及格式說明
CAN總線是通過以下5種類型的幀進(jìn)行通信:
數(shù)據(jù)幀:用于發(fā)送單元向接收單元傳送數(shù)據(jù)的幀
遙控幀:用于接收單元向具有相同 ID 的發(fā)送單元請(qǐng)求數(shù)據(jù)的幀
錯(cuò)誤幀:用于當(dāng)檢測(cè)出錯(cuò)誤時(shí)向其它單元通知錯(cuò)誤的幀
過載幀:用于接收單元通知其尚未做好接收準(zhǔn)備的幀
幀間隔:用于將數(shù)據(jù)幀及遙控幀與前面的幀分離開來的幀
數(shù)據(jù)幀和遙控幀有標(biāo)準(zhǔn)格式和擴(kuò)展格式兩種格式,標(biāo)準(zhǔn)格式有11個(gè)位的標(biāo)識(shí)符ID,擴(kuò)展格式有29個(gè)位的ID。 ? 1、 數(shù)據(jù)幀
? 如上圖所示,數(shù)據(jù)幀由7個(gè)段構(gòu)成:
幀起始:表示數(shù)據(jù)幀開始的段
仲裁段:表示該幀優(yōu)先級(jí)的段
控制段:表示數(shù)據(jù)的字節(jié)數(shù)及保留位的段
數(shù)據(jù)段:數(shù)據(jù)的內(nèi)容,可發(fā)送 0~8 個(gè)字節(jié)的數(shù)據(jù)
CRC段:檢查幀的傳輸錯(cuò)誤的段
ACK段:表示確認(rèn)正常接收的段
幀結(jié)束:表示數(shù)據(jù)幀結(jié)束的段
理解數(shù)據(jù)幀的含義,請(qǐng)從認(rèn)真理解它的定義:用于發(fā)送單元向接收單元傳送數(shù)據(jù)的幀。 ? 一般的CAN總線通信,總線上通信絕大部分時(shí)候都是數(shù)據(jù)幀。像在CANOpen協(xié)議中,用的最多的PDO過程數(shù)據(jù)對(duì)象就是通過數(shù)據(jù)幀進(jìn)行的通信。 ? 初學(xué)者可以先理解數(shù)據(jù)幀,然后其他就容易理解了。下面,我們?cè)賮碇v述一下數(shù)據(jù)幀7段的詳情。 ? 幀起始:標(biāo)準(zhǔn)和擴(kuò)展格式相同。表示幀開始的段,1個(gè)位的顯性位,如下圖所示: ?
? 總線上的電平有顯性電平和隱性電平兩種。總線上執(zhí)行邏輯上的線“與”時(shí),顯性電平的邏輯值為“0”,隱性電平為“1”。 ? “顯性”具有“優(yōu)先”的意味,只要有一個(gè)單元輸出顯性電平,總線上即為顯性電平。并且,“隱性”具有“包容”的意味,只有所有的單元都輸出隱性電平,總線上才為隱性電平。(顯性電平比隱性電平更強(qiáng)) ? 仲裁段:標(biāo)準(zhǔn)格式和擴(kuò)展格式在此的構(gòu)成有所不同。仲裁段表示該幀優(yōu)先級(jí)的段,擴(kuò)展格式多了18位ID,如下圖所示: ?
? RTR = 0代表數(shù)據(jù)幀,RTR = 1代表遠(yuǎn)程幀。 ? 為什么叫仲裁段,就是通過ID來判斷總線上哪一個(gè)節(jié)點(diǎn)具有優(yōu)先發(fā)送的權(quán)利。ID越小(0代表顯性),優(yōu)先級(jí)越高。 ? 控制段:標(biāo)準(zhǔn)和擴(kuò)展格式的構(gòu)成有所不同。控制段由 6 個(gè)位構(gòu)成,如下圖所示: ?
? 它們除了都有4位表示數(shù)據(jù)段長度代碼(DLC)外,標(biāo)準(zhǔn)幀有IDE(數(shù)值為0)位和r0保留位,擴(kuò)展幀有r0和r1保留位。 ? 保留位必須全部以顯性電平發(fā)送。但接收方可以接收顯性、隱性及其任意組合的電平。 ? 數(shù)據(jù)段:標(biāo)準(zhǔn)和擴(kuò)展格式相同。數(shù)據(jù)段表示傳輸數(shù)據(jù)的內(nèi)容,從 MSB(最高位)開始輸出,可發(fā)送 0~8 個(gè)字節(jié)的數(shù)據(jù),長度由前面控制段決定。 ? CRC段:標(biāo)準(zhǔn)和擴(kuò)展格式相同。CRC段是檢查幀傳輸錯(cuò)誤的幀,由 15 個(gè)位的 CRC 順序和 1 個(gè)位的 CRC 界定符(用于分隔的位)構(gòu)成。 ?
? 相比485這類通信,CAN控制器就已經(jīng)把CRC校驗(yàn)做了,不需要你的程序再次去計(jì)算,從而節(jié)約了處理器資源。 ? ACK段:標(biāo)準(zhǔn)和擴(kuò)展格式相同。ACK段用來確認(rèn)是否正常接收。由 ACK 槽(ACK Slot)和 ACK 界定符 2 個(gè)位構(gòu)成。 ?
? A.?發(fā)送單元在 ACK 段發(fā)送 2 個(gè)位的隱性位。 ? B.?接收到正確消息的單元在 ACK 槽(ACK Slot)發(fā)送顯性位, 通知發(fā)送單元正常接收結(jié)束。這稱作“發(fā)送 ACK”或者“返回 ACK”。 ?
幀結(jié)束:標(biāo)準(zhǔn)和擴(kuò)展格式相同。幀結(jié)束是表示該該幀的結(jié)束的段。由 7 個(gè)位的隱性位構(gòu)成。 ?
? 2、遙控幀
和數(shù)據(jù)幀相比,遙控幀是接收單元向發(fā)送單元請(qǐng)求發(fā)送數(shù)據(jù)所用的幀。所以,遙控幀沒有數(shù)據(jù)段。因此,遙控幀由如下 6 個(gè)段組成:
幀起始(SOF):表示幀開始的段
仲裁段:表示該幀優(yōu)先級(jí)的段。可請(qǐng)求具有相同ID的數(shù)據(jù)幀
控制段:表示數(shù)據(jù)的字節(jié)數(shù)及保留位的段
CRC段:檢查幀的傳輸錯(cuò)誤的段
ACK段:表示確認(rèn)正常接收的段
幀結(jié)束:表示遙控幀結(jié)束的段
這6個(gè)段和上面數(shù)據(jù)幀的內(nèi)容基本一樣,這里就不一一講述了。下面,講一下遙控幀和數(shù)據(jù)幀的區(qū)別:
一是,遙控幀的 RTR 位為隱性位,沒有數(shù)據(jù)段;二是,沒有數(shù)據(jù)段的數(shù)據(jù)幀和遙控幀可通過 RTR 位區(qū)別開來。
問題一:遙控幀沒有數(shù)據(jù)段,數(shù)據(jù)長度碼該如何表示? ? 遙控幀的數(shù)據(jù)長度碼以所請(qǐng)求數(shù)據(jù)幀的數(shù)據(jù)長度碼表示。 ?
問題二:沒有數(shù)據(jù)段的數(shù)據(jù)幀有何用途? ? 例如,可用于各單元的定期連接確認(rèn)/應(yīng)答、或仲裁段本身帶有實(shí)質(zhì)性信息的情況下。 ?
3、錯(cuò)誤幀
? 用于在接收和發(fā)送消息時(shí)檢測(cè)出錯(cuò)誤通知錯(cuò)誤的幀。錯(cuò)誤幀由錯(cuò)誤標(biāo)志和錯(cuò)誤界定符構(gòu)成。
? (1) 錯(cuò)誤標(biāo)志 ? ?
錯(cuò)誤標(biāo)志包括主動(dòng)錯(cuò)誤標(biāo)志和被動(dòng)錯(cuò)誤標(biāo)志兩種:
主動(dòng)錯(cuò)誤標(biāo)志:6 個(gè)位的顯性位
被動(dòng)錯(cuò)誤標(biāo)志:6 個(gè)位的隱性位
(2) 錯(cuò)誤界定符 ? 錯(cuò)誤界定符由 8 個(gè)位的隱性位構(gòu)成。 ?
4、過載幀
? 過載幀是用于接收單元通知其尚未完成接收準(zhǔn)備的幀。過載幀由過載標(biāo)志和過載界定符構(gòu)成: ? 過載標(biāo)志:6 個(gè)位的顯性位,過載標(biāo)志的構(gòu)成與主動(dòng)錯(cuò)誤標(biāo)志的構(gòu)成相同。 ? ? 過載界定符:8 個(gè)位的隱性位,過載界定符的構(gòu)成與錯(cuò)誤界定符的構(gòu)成相同。 ?
5、幀間隔
? 幀間隔是用于分隔數(shù)據(jù)幀和遙控幀的幀。數(shù)據(jù)幀和遙控幀可通過插入幀間隔將本幀與前面的任何幀(數(shù)據(jù)幀、遙控幀、錯(cuò)誤幀、過載幀)分開。 ? 過載幀和錯(cuò)誤幀前不能插入幀間隔。 ? (1) 間隔 ? 3 個(gè)位的隱性位。 ? (2) 總線空閑 ? 隱性電平,無長度限制(0 亦可);本狀態(tài)下,可視為總線空閑,要發(fā)送的單元可開始訪問總線。 ?
(3) 延遲傳送(發(fā)送暫時(shí)停止)
8 個(gè)位的隱性位,只在處于被動(dòng)錯(cuò)誤狀態(tài)的單元?jiǎng)偘l(fā)送一個(gè)消息后的幀間隔中包含的段。
編輯:黃飛
?
評(píng)論
查看更多