截取地址:https://www.e-learn.cn/content/qita/715699
什么是CANOPEN協議
CANOPEN協議是基於CAN總線協議建立的應用層協議。
CANOPEN協議屬於“主-從站協議”,一個CANOPEN網絡中有一個主站和若干個從站。
每一個從站點都有一個ID號,一個數據字典和四種工作狀態。
CANOPEN協議將CAN總線協議的通信幀進行了進一步的封裝和分類,以滿足更高層次通信的需要。
CANOPEN數據字典
CANOPEN網絡中的每一個從站設備都要有一個數據字典,其實數據字典這個翻譯不太准確,應該叫做“命令ID與功能對照表”。
比如網絡中有一個信號燈設備,則這個設備就可能有這樣一個數據字典。
| index | subIndex | data | 功能 |
|---|---|---|---|
| 0x400 | 0 | 0 | 開燈 |
| 0 | 1 | 關燈 |
其中index我們可以理解為“命令ID”,subIndex可以理解為“子ID”。
這個“字典”表示,只要有其他設備向信號燈發送一條包含命令ID為0x400和子ID為0的命令,如果data為0,則信號燈就亮;如果data為1,則信號燈就滅。所以說“數據字典”更像是“命令ID與功能對照表”。
實際上,CANOPEN協議規定了設備數據字典的格式,並對命令ID號進行了規定和划分(具體的規定很復雜,需要請參閱規范)。
有一些命令ID的功能是固定的,有一些則可以由設備生產廠家自己決定。命令ID對應的功能也不總是操作這個設備,也可以是讀取這個設備的信息,比如設備名等。
接下來的問題是如何向一個設備發送命令ID呢?對此,CANOPEN協議也有規定,在下文中會進行介紹。
設備ID與常用通信對象
CANOPEN協議是一個“主-從站協議”,其中規定,在總線上每一個作為“從站”的設備要有一個自己的設備ID(主站設備不做強制要求)。
這個ID稱為Node-ID,這個英文名字在許多文章中更常見,范圍是1~127(0有特殊用途,不能作為ID分配給設備)。
同一個總線上不能出現ID號相同的兩個從站設備。所以,基於CANOPEN協議的總線上最多有127個從站設備。
那么為什么是127個呢,為了解釋這個問題,要先了解CANOPEN協議規定的通信對象。
就像CAN總線協議的基本通信單元稱為“幀”一樣,CANOPEN協議的基本通信單元叫做“通信對象”(英文為Object,姑且這么翻譯吧)。
常用的通信對象有NMT、SYNC、EMERGENCY、TIME STAMP、SDO、PDO。
他們結構相同,包括funciton Code、Node-ID、DLC(數據長度)、DATA(數據)四部分構成。
本質上都是通過封裝CAN總線協議的數據幀實現的。
他們的不同體現在DATA這個部分,有的對象DATA部分可以完全用來傳輸數據,有的對象針對DATA部分進一步做了划分和要求。
上文說過,CAN總線協議的數據幀包含一個仲裁段,其前11位是幀ID。CANOPEN協議進一步把幀ID分為FunctionCode和Node-ID兩部分,如下:
| function Code | Node-ID |
|---|---|
| 4 | 7 |
由於Node-ID只有7位,最大值為127,所以CANOPEN協議的總線上最多有127個從站設備。functionCode和Node-ID在一起又被稱為COB-ID。
DLC則對應數據幀控制段的后4位,表示后續負載數據的長度。
DATA與數據幀的數據段長度相同,至於有何用途,不同對象有不同要求。
| functionCode | Node-ID | DLC | DATA |
|---|---|---|---|
| 4bit | 7bit | 4bit | 8*8bit |
可見,CANOPEN協議的通信對象就是數據幀,只是進一步規定了數據幀的內容格式,所以說CANOPEN協議是基於CAN總線協議的應用層協議。
PDO對象
上文中提到常用的通信對象有NMT、SYNC、EMERGENCY、TIME STAMP、SDO、PDO,每一種通信對象都有自己的用途。本章重點介紹PDO對象,了解了這個對象的機理,其他對象也可以融會貫通。
1 PDO對象概述
PDO對象稱為“過程數據對象”,用於無連接的數據傳輸,即A站發送數據給B站后,不需要等待B站給出確認收到的應答。當然B站也可以應答一些信息給A站,這個有點像網絡通信中的UDP協議,即應答不是強制要求的,B站可以回答,也可以不回答。
PDO對象的DATA部分可以完全用來傳輸數據,沒有進步做要求。
根據上文知道,CAN總線本質上是廣播的,對於B站來說,它面臨三個問題(假設B站是主站):
- 總線上的通信對象是不是PDO對象,因為不同對象的數據部分的含義是不同的,需要不同的方式去解析;
- 如何知道PDO對象是A站發出的;
- 如何回答,即發送PDO給A站。
對於問題1,B站是通過讀取functionCode來判斷當前總線上是不是PDO對象的。上文提到functionCode有4bit位,即有16個不同的functionCode。
CANOPEN協議並沒有硬性規定PDO對象必須使用那一個(或幾個)functionCode,A站和B站可以自行約定。
但是CANOPEN協議給了一個划分的《建議》(用書名號只是為了強調,不是真有一本叫做建議的書),既然是建議,你可以遵守也可以不遵守,但事實上,只要不是特殊情況,所用人都遵守了這個《建議》,如下:
| 對象 | functionCode | Node-ID | COB-ID |
|---|---|---|---|
| NMT(Model Control) | 0x0 | 0x0 | 0x0 |
| SYNC | 0x1 | 0x0 | 0x80 |
| TIME STAMP | 0x2 | 0x0 | 0x100 |
| EMERGENCY | 0x1 | 0x1-0x7F | 0x81-0xFF |
| PDO | 0x3-0xA | 0x1-0x7F | 0x181-0x57F |
| SDO | 0xB-0xC | 0x1-0x7F | 0x581-0x67F |
| NMT(ERROR) | 0xD | 0x1-0x7F | 0x701-0x77F |
對於問題2和問題3,我們先假設A站的Node-ID為1,並且需要進一步引入TPDO和RPDO的概念才能解決。
從上表中我們注意到PDO的functionCode是一個范圍,共8個,即functionCode在此范圍內的所有通信對象都是PDO對象。剛才提到的《建議》進一步對PDO進行了細分。以A站的PDO為例,如下表:
| 對象 | functionCode | Node-ID | COB-ID |
|---|---|---|---|
| TPDO1 | 0x3 | 0x1 | 0x181 |
| RPDO1 | 0x4 | 0x1 | 0x201 |
| TPDO2 | 0x5 | 0x1 | 0x281 |
| RPDO2 | 0x6 | 0x1 | 0x301 |
| TPDO3 | 0x7 | 0x1 | 0x381 |
| RPDO3 | 0x8 | 0x1 | 0x401 |
| TPDO4 | 0x9 | 0x1 | 0x481 |
| RPDO4 | 0xA | 0x1 | 0x501 |
通過上表,我們可以看出,從站A可以擁有8個PDO對象,其中4個為TPDO,4個為RPDO。下面來回答問題2,B站“如何知道PDO是A站發來的?”。答案就是檢測PDO對象是否屬於A站的TPDO,即COB-ID等於0x181,0x281,0x381或0x481。
對於問題3,答案是B站(主站)發送屬於A站的RPDO。A站檢查到總線上有自己的RPDO就知道數據是發送給自己的。
2 PDO對象的引申問題
上一節講了“主-從”站間PDO對象的通信原理。不過有一個大前提就是我們遵循了《建議》,這就引申出如下兩個問題:
- 《建議》給每個從站分配了4個RPDO對象,即每次主站最多只能發送4*8BYTE(64字節)的數據給從站,不夠怎么辦?
- 從站與從站之間如何通信?
對於問題1,答案是不去遵守《建議》,自己根據需要規定,比如將0x281也規定為RPDO也可以,只要主站和從站都遵守這個規定就行。但這種情況是不多見的,因為《建議》本身是許多廠商共同商討的結果,顯然滿足絕大部分應用情況。
對於問題2,其實超出了CANOPEN協議的應用范圍,因為CANOPEN協議是“主-從站”協議,這類協議的特點就是從站之間沒有通信的渠道。如果需要通信,也是通過主站中轉。比如從站A發給主站,主站再發給從站B,來實現從站A與從站B的通信。從我的工業經驗來看,這種從站之間通信的情況就沒發生過。
SDO對象
有了PDO對象的基礎,SDO對象的說明就容易多了。
- SDO對象也分為TSDO和RSDO兩種。(遵循《建議》)
- SDO對象是用來操作從站設備的數據字典的。
- SDO對象是一個有應答的通信對象,即主站發送RSDO給從站后,從站如果接收到,必須發送TSDO給主站進行應答。
- SDO對象對DATA段進行了進一步的規定和划分。
以下為SDO對象的結構
| functionCode | Node-ID | DLC | ControlCode | Index | SubIndex | data |
|---|---|---|---|---|---|---|
| 4bit | 7bit | 4bit | 8bit | 16bit | 8bit | 32bit |
其中ControlCode、Index、SubIndex和data就是DATA部分,SDO對象對此進行了細分規定。Index,SubIndex和data的含義,可以參考前文數據字典部分的信號燈的例子。
ControlCode在RSDO中經常表示此次操作是寫入數據字典還是讀取數據字典,在TSDO中表示寫入是否成功,或者錯誤碼一類的。雖然只有8bit,但是其構成還是挺復雜的,這里就不詳細描述了,可以在網上找更加詳細的文檔來看。
