標籤:

Matlab如何實現CAN Matrix的dbc與excel之間的一鍵轉換

在進入職場之初,非常有幸加入了一個大項目。

其n中有一部分任務是關於CAN Matrix的。當然,這部分工作不在我的任務範疇內,同時也因為我並不是讀這方面的專業,所以這篇帖子關於CAN nMatrix深層次的問題,我能力有限無法作答。如果有想了解CAN匯流排方面的朋友,我推薦知乎上的一個問題「如何進行汽車CAN匯流排開發」,其中王博士n(@Wang Yu)的回答很全面。

在n關於CAN Matrix這部分工作內容中,需要整合各個供應商的CAN Matrix,最終形成一個總的CANMatrix。這個過程中CAN nMatrix需要以兩種類型的形式體現,一種就是dbc,另一種是excel。我並不確定這種情況是不是普遍現象,而且作為初學者而言,個人認知n是,dbc是CAN網路的配置文件,而excel表格能夠更直觀地體現CAN nMatrix,同時更便於在一個項目中不同工程師之間的協作以及數據的管理。

正如我先前所提到的,CAN Matrix方面的工作並不在我的任務範疇內,不過一直以來我都在思考一個問題,是否存在一個方法,能夠實現dbc與excel之間的一鍵轉換。

很高興,在舍夫沙萬奮戰5個小時,我通過Matlab實現了dbc與excel之間一鍵轉換的功能。接下來,我來分享下,寫這段代碼過程中需要注意的幾點細節以及相關的Matlab函數。

1. dbc轉excel

首先,先來聊一聊,如何將dbc文件映射到excel中,其中需要注意四個方面的細節,這四個方面的細節理順了之後,寫代碼就會清晰許多。

● Matlab如何讀取dbc文件

● dbc文件是如何定義節點,信息及信號的

● excel如何呈現CAN Matrix

● layout的處理

1.1 Matlab如何讀取dbc文件

在先前的幾篇帖子中,都提到過Matlab如何讀取txt文件。讀取dbc文件的方式與讀取txt文件類似,只是拓展名上的區別,在這裡,我簡單的介紹下我最常用的兩種方式:

1)

fin=fopen(file.dbc,r);

text=fscanf(fid,%s);

fclose(fid);

通n過這種方式讀取出來的結果有個特點,所讀取的結果,其數據類型是char,中間的空格以及換行信息都會被忽略,不過讀取速度較快。如果對輸出結果的格式沒n有特殊要求的話,優先考慮這種讀取方式。不過對於dbc,為了避免獲取不正確或者多餘的信息,這種方式並不推薦,建議使用下一種方式。

2)

fin=fopen(file.dbc,r);

text_line = {};

ct = 1;

while ~feof(fin)

text_line(ct,1) = {fgets(fin)};

ct = ct+1;

end

fclose (fin);

這種讀取方式,相比第一種,速度會稍慢一些,輸出結果的數據類型是cell的形式,不過保留了原來文本的格式信息,包括空格以及換行。

1.2 dbc文件是如何定義節點,信息及信號的

以.txt文件的格式或者通過Notepad++就可以查看dbc文件背後的代碼。以下所舉例的代碼,僅呈現代碼格式,代碼內容只是例子。

dbc中節點的定義如下所示:

BU_: ECU1 ECU2 ECU3 ECU4

表示CAN網路中存在4個節點,分別為ECU1,ECU2,ECU3以及ECU4這四個控制器。腳本中可以識別『BU_:』這個關鍵字來定位節點定義。

dbc中信息的定義如下所示:

BO_ 791 ECU1_Msg1: 8 ECU1

其中「791」表示信息的ID,以十進位表示。通過dec2hex函數,可以實現十進位與十六進位之間的轉換,不過輸出的結果數據類型為字元串。

dec2hex(791)

>> ans = 317

「ECU1_Msg1」表示該Message的名字,而最末尾的「ECU1」表示信息的發送控制器。腳本中可以識別『BO_』這個關鍵字來定位信息定義。

dbc中信號的定義如下所示:

SG_ ECU1_Signal1 : 55|1@0+ (1,0) [0|1] "A" ECU2

其n中「ECU1_Signal1」表示該信號的名字,「55|1」分別表示信號在信息layout中的起始位置,以及信號長度。「(1,0)」分別表示信號n的精度及偏移量。「[0|1]」分別表示信號的最大值與最小值。「A」表示信號的單位。「ECU2」表示信號的接收控制器。腳本中可以識別『SG_』這個n關鍵字來定位信息定義。

那麼信號的解釋,狀態的定義等分別是在哪裡定義的?

M_ SG_ 791 ECU1_Signal1 "just for test";

信號解釋的定義如上述代碼所示。其中需要注意信息ID及信號名的匹配,引號中的文字即為該信號的注釋。可以通過「M_ SG_」加上相應的ID及信號名可以定位到相應的信號解釋。

VAL_ 791 ECU1_Signal1 1 "error" 0 "no error" ;

信號狀態的定義如上述代碼所示。與信號解釋的定義類似,該代碼包含了信息ID及信號名的信息。以該信號為例,狀態量1表示錯誤狀態,狀態量0表示無錯誤狀態。可可以通過「VAL_」加上相應的ID及信號名可以定位到相應的信號解釋。

類似的,可以在dbc腳本文件中找到信號發送的數據類型及發送周期的相應的代碼。這裡就不再一一闡述。

1.3 excel如何呈現CAN Matrix

從1.2中可以了解到,dbc文件中涵蓋了很多信息,包括信號ID,信號的layout,精度,偏移量,最大最小值,等等。那麼,是不是所有信息都要映射到excel中去?這個問題的答案得按情況來區分。

如果整體的需求,僅僅只是從dbc到excel的一鍵轉換,那麼可以有選擇性的從dbc中篩選出部分信息映射到excel中。

但是如果整體的需求是,dbc與excel之間雙向可逆的一鍵轉換,那麼必須將dbc中所有的信息映射到excel中。而不至於從excel轉換成dbc過程中出現信息的缺失。

所以1.3這部分關於excel如何呈現CAN Matrix中,我想論述的就是,CAN Matrix的表現形式需要根據具體的整體需求來進行。

1.4 layout的處理

在整個處理過程中,之前的幾點細節,主要涉及到信息的抓取,這部分內容與網路爬蟲有點類似,都是涉及到字元信息的處理。這部分更多的細節,可以參考Matlab還能看得懂上海房價?的爬蟲帖子。

此外,這個過程中一個特別意思的問題,就是關於layout的處理,一個十分純粹的數據處理,有點繞,接下來我來分享一下這個處理過程。

假設有一個信號叫做「ECU1_Signal1」,Byte Order為Motorola,長度為10,信號佔據的位置為「0-5;12-15」。具體的layout信息如下圖所示:

但是這段layout信息在dbc中的表現形式是:

SG_ ECU1_Signal1 : 5|10@0+ (1,0) [0|1] "A" ECU2

「5|10」就是相應的位置信息。那麼如何從「5|10」映射到「0-5;12-15」,並且以此類推適用到其他不同類型的layout。

對此,我在Matlab中寫了一個函數,題頭為:

function layout = layout_dbc(sig_p,sig_l)

其中sig_p對應的是信號在信息layout中的起始位置,而sig_l對應的是信號長度。以ECU1_Signal1為例,sig_p=5,sig_l=10,輸出的結果將會是「0-5;12-15」

在每個信號layout形式轉換過程中,調用這個函數,可以實現layout信息格式的轉換。不過這其中還需要改進的是,這個函數只針對Motoraola,並不適用Intel。在接下來改進的環節中,可以在函數中增加這個變數,使函數的使用範圍更廣。

關於其中的演算法,比較簡單,思路清晰的話,實現這個函數沒有難度。其中可以使用ceil函數:

ceil((sig_l-row_left)/8);

ceil函數是一個求整函數,通過信號長度除以8,可以判斷這個信號跨幾行。

接下來,千萬不要使用枚舉法,把每種情況列舉一遍,耗時比較長,代碼寫的也比較繁瑣,並且容易出錯。

建議使用一個for循環,以跨行數量為導向,以8位係數,進行處理。

2. excel轉dbc

關n於從excel到dbc的一鍵轉換,這裡就不再深入闡述,意義不大。在熟悉dbc代碼框架之後,就是dbc到excel轉換的逆向過程,類似於一道填空n題。唯一需要注意的是,正如我在之前提到的,excel中CAN Matrix的模塊所涵蓋的信息一定要全面,足以能夠生成dbc。

以上

如果你有新的想法,可以給我留言,我們互相探討

如果你覺得我還不錯,可以關注我的微信公眾號「打浦橋程序員」,謝謝

推薦閱讀:

TAG:MATLAB |