1 緒論現場總線,就是應用于工業現場,采用總線方式連接多個設備,用于傳輸工業現場各種數據的一類通信系統[1]。CAN(Controller Area Network)總線是現場總線的一個分支,因其具有很高的可靠性和性能價格比,已經成為國際標準,在工業過程監控設備的互連方面得到廣泛應用,受到工業界的廣泛重視,并已被公認為幾種最有前途的現場總線之一。
1.1 研究背景隨著計算機硬件、軟件技術及集成電路技術的迅速發展,工業控制系統已成為計算機技術應用領域中最具活力的一個分支,并取得了巨大進步。由于對系統可靠性和靈活性的高要求,工業控制系統的發展主要表現為:控制多元化,系統面向分散化,即負載分散、功能分散、危險分散和地域分散。分散式工業控制系統就是為適應這種需要而發展起來的。這類系統是以微型機為核心,將5C技術——Computer(計算機技術)、Control(自動控制技術)、Communication(通信技術)、CRT(顯示技術)和Change(轉換技術)緊密結合的產物。它在適應范圍、可擴展性、可維護性以及抗故障能力等方面,較之分散型儀表控制系統和集中型計算機控制系統都具有明顯的優越性。典型的分散式控制系統有現場設備、接口與計算設備以及通信設備組成,現場總線(Field bus)就是在這種背景下產生的[2]。
1.2 研究目的和意義從19世紀發明汽車以來,人們就一直在乘坐的舒適性、安全性和操控性方面不停地對其進行改革和創新,車上的電子設備也越來越多。這些電子設備大多是需要協同工作的,這就要求各部件之間能互相通信[1]。
為了解決汽車通信問題,CAN—bus應運而生,憑借可靠、實時、經濟和靈活的特點,CAN總線很快在其他行業得到廣泛應用,特別是在工業控制領域更是如魚得水。現在CAN—bus總線已經成為全球范圍內最重要的現場總線之一,甚至引領著現場總線的發展。
工業控制系統涉及眾多軟、硬件模塊,給程序的設計和調試帶來一定難度。尤其作為上、下位機間聯系紐帶的CAN總線通信部分,一旦在整個系統運行期間發生問題,若沒有良好的人機界面和測試手段,將很難及時準確地找到并排除故障。同樣,在控制系統的研制過程中,為了盡可能地減少故障和縮小故障范圍,也應設計相應的測試軟件來具體負責CAN總線通信及接口部分的調試、運行任務。故此,本課題就如何利用VC設計CAN總線測試軟件進行介紹。
1.3 國內外發展現狀自從Bosch與Intel公司于1986年正式發布CAN—bus通信方式,寶馬(BMW)公司很快于1989年推出第一款使用CAN—bus通信的汽車,從此 CAN—bus開始了其輝煌的歷程:(1)1990年,奔馳公司發布了第一輛使用CAN—bus的轎車,現在幾乎每一輛新生產的汽車均裝配有CAN—bus網絡;(2)1993年,CAN—bus總線被制定成為國際標準ISO11898(高速應用)和ISO11519(低速應用);(3)1994年,歐洲成立了CiA廠商協會,美洲成立了ODVA廠商協會,專門支持CAN—bus總線的兩大應用層協議——CANopen協議與DeviceNet協議[3]。
在CiA的努力推廣下,CAN技術在汽車電子控制系統、電梯控制系統、安全監控系統、醫療儀器、紡織機械、船舶運輸等方面均得到了廣泛的應用。現已有400多家公司加入了CiA,CiA已成為全球應用CAN技術的權威。
國內在CAN總線方面的研究和應用于國外相比還存在明顯的差距,體現在兩個方面:(1)國內在自主研究和開發汽車電子CAN網絡方面尚處于試驗和起步階段,國內絕大部分的汽車還沒有采用汽車總線設計;(2)國內汽車合資企業不少已采用CAN總線技術,但核心技術掌握在外商手中。為順應世界汽車工業發展的趨勢,我國也相應加強了對CAN總線的研究,并開發具有自主知識產權的CAN總線產品。
CAN技術已應用于家用電器和智能樓宇以及小區建設中。隨著無線技術的完善和將無線技術應用到CAN總線系統中研究的不斷深入,可以樂觀地預計,未來CAN總線技術的應用將無處不在,虛擬的CAN總線即將誕生[5]。
1.4 論文結構安排本文第一章介紹了CAN總線的研究背景和國內外發展現狀,并介紹本課題研究的目的和意義。第二章簡單介紹了CAN總線通信規范和SJA1000控制器。第三章簡單介紹了開發環境和CAN接口卡。第四章詳細介紹了軟件的設計過程,包括驅動安裝、接口卡函數庫說明、界面設計、功能分析與設計。第五章介紹了軟件的測試及程序的發布。
2 CAN總線協議分析2.1 CAN-bus 規范V2.0 版本CAN 規范技術規范由兩部分組成:
• A 部分:CAN 的報文格式說明(按CAN1.2 規范定義)。
• B 部分:標準格式和擴展格式的說明。
2.1.1 CAN的分層結構在CAN V2.0A里,CAN被細分為三個層次:對象層、傳輸層、物理層。
而在PartB中,CAN被細分為兩個層次:數據鏈路層(邏輯鏈路控制子層LLC、媒體訪問控制子層MAC)、物理層。
2.1.2 報文傳輸(1)幀類型
報文傳輸由5種類型的幀所表示和控制,它們分別是數據幀、遠程幀、錯誤幀、過載幀和幀間隔,其用途如表2.1所列。
表2.1 幀的類型及用途
| |
| 用于發送節點向接受節點傳送數據,是使用最多的幀類型 |
| |
| 用于檢測出通信錯誤(如校驗錯誤)時向其他節點發送通知 |
| 用以在先行的和后續的數據幀(或遠程幀)之間提供一附加的延時 |
| |
1) 數據幀
數據幀由7 個不同的位場組成:幀起始、仲裁場、控制場、數據場、CRC 場、應答場、幀結尾。數據幀各段的功能如表2.2所列。
表2.2 數據幀各段的功能
| | |
| | 表示數據幀開始,由單個顯性位構成,在總線空閑時才允許發送 |
| | | 表示該幀的優先級,由11位ID碼和1位遠程幀標志位(RTR)組成 |
| | 表示該幀的優先級,由29位ID碼、1位替代遠程幀請求位(SRR)、1位標志位擴展位(IDE)和1位遠程幀標志位(RTR)組成 |
| | |
| | |
| | 檢查幀的傳輸錯誤,范圍包括從幀起始到數據段的所有內容(不包括填充位) |
| | |
| | |
2) 遠程幀
遠程幀由6 個不同的位場組成:幀起始、仲裁場、控制場、CRC 場、應答場、幀結尾。
3) 錯誤幀
錯誤幀由兩個不同的場組成。第一個場用作為不同站提供的錯誤標志的疊加。第二個場是錯誤界定符。錯誤標志有兩種形式,主動錯誤標志和被動錯誤標志。錯誤界定符包括8 個“隱性”的位。
4) 過載幀
過載幀包括兩個位場:過載標志和過載界定符。
5) 幀間空間
數據幀(或遠程幀)與其前面幀的隔離是通過幀間空間實現的,無論其前面的幀為何類型(數據幀、遠程幀、錯誤幀、過載幀)。所不同的是,過載幀與錯誤幀之前沒有幀間空間,多個過載幀之間也不是由幀間空間隔離的。
(2)發送器/接收器的定義
發送器:產生報文的單元被稱之為報文的“發送器”。此單元保持作為報文發送器直到總線出現空閑或此單元失去仲裁為止。
接收器:如果有一單元不作為報文的發送器并且總線也不空閑,則這一單元就被稱之為報文的“接收器”。
2.1.3 報文檢驗校驗報文是否有效的時間點,對于發送器與接收器是各不相同的。
對于發送器:如果直到幀的末尾位均沒有錯誤,則此報文對于發送器有效。如果報文破損,則報文會根據優先權自動重發。為了能夠和其他信息競爭總線,重新傳輸必須在總線空閑時啟動。
對于接收器:如果直到一最后的位(除了幀末尾位)均沒有錯誤,則報文對于接收器有效。
2.1.4 編碼位流編碼:幀的部分,諸如幀起始、仲裁場、控制場、數據場以及CRC序列,均通過位填充的方法編碼。
數據幀或遠程幀(CRC界定符、應答場和幀末尾)的剩余位場形式相同,不填充。錯誤幀和過載幀的形式也相同,但并不通過位填充的方法進行編碼。
報文里的位流采用不歸零編碼(NRZ),這就是說,在整個位時間里,位電平要么為“顯性”,要么為“隱性”。
2.1.5 錯誤處理錯誤檢測:有5種不同的錯誤類型(這5種錯誤不會相互排斥):位錯誤、填充錯誤、CRC錯誤、形式錯誤、應答錯誤
錯誤標志:檢測到錯誤條件的站通過發送錯誤標志指示錯誤。
2.1.6 故障界定至于故障界定,單元的狀態可能為以下三種之一:
錯誤主動:可以正常地參與總線通訊并在錯誤被檢測到時發出主動錯誤標志。
錯誤被動:不允許發送主動錯誤標志。
總線關閉:不允許在總線上有任何的影響(比如,關閉輸出驅動器)。
2.1.7 位定時要求標稱位速率:標稱位速率為一理想的發送器在沒有重新同步的情況下每秒發送的位數量。
標稱位時間:標稱位時間=1/標稱位速率
可以把標稱位時間劃分成幾個不重疊的時間片段,它們是:同步段、傳播時間段、相位緩沖段1、相位緩沖段2。
2.1.8 報文濾波在CAN2.0B中,還增加了有關報文濾波的定義。
報文濾波取決于整個識別符。允許在報文濾波中將任何的識別符位設置為“不考慮”的可選屏蔽寄存器,可以選擇多組的識別符,使之被映射到隸屬的接收緩沖器里。
如果使用屏蔽寄存器,它的每一個位必須是可編程的,即,他們能夠被允許或禁止報文濾波。屏蔽寄存器的長度可以包含整個識別符,也可以包含部分的識別符。
2.1.9 振蕩器容差由于給定的最大的振蕩器,其容差為1.58%,因此憑經驗可將陶瓷諧振器使用在傳輸率高達125kbit/s的應用罩。
為了滿足CAN協議的整個總線速度范圍,需要使用晶振。具有最高振蕩準確度要求的芯片,決定了其他節點的振蕩準確度。
2.2 CAN控制器SJA1000下位機的CAN總線網絡接口使用Philips公司的SJA1000芯片,SJA1000是一個獨立的CAN控制器,具有一系列先進的功能,適合于多種應用,特別在系統優化、診斷和維護方面非常重要。
SJA1000具有完成CAN總線通信協議所要求的全部特性,它與獨立CAN總線控制的PCA82C200完全兼容,并有支持CAN2.0B協議、擴展接收緩沖器、增強錯誤處理能力和增強驗收濾波功能等新增功能。
SJA1000可以直接進行CAN總線互聯,而PC機作為上位機,是通過USB電纜連接到CAN接口卡上的,這里我們使用的是普創電子的CANUSB—Ⅱ工業級雙路智能接口卡。該接口卡中的CAN總線數據收發也是由SJA1000CAN控制器和82C250CAN收發器完成的,主機通過USB電纜來訪問CAN控制器,從而實現數據通信。
2.3 本章小結本章主要介紹了CAN總線通信系統上位機通信軟件的設計所涉及的基本知識,包括CAN—bus規范和CAN控制器SJA1000,有了這些知識,才能保證軟件設計得以順利開展。
3 開發環境介紹3.1 開發環境CAN總線通信系統上位機通信軟件的設計應具有直觀的窗口外觀,豐富、人性化的友好界面,便于操作和維護。而Visual C++6.0編譯器提供了強大的輔助工具集,利用這些工具可以很方便的設計出本課題所要求的應用程序。
利用Visual C++6.0開發應用程序時,主要有兩種方法,一種是利用Windows本身提供的API函數編程,另一種是直接使用Miscrosoft提供的MFC類庫編程。本課題使用的是MFC類庫編程。
MFC類庫是由Microsoft公司提供的用來編寫Windows應用程序的C++類集合,在該類集合封裝了Windows大部分編程對象和與它們相關的操作。MFC為用戶提供了一個Windows環境下的應用程序框架和創建應用程序的組件,使用這個應用程序框架和組件,可以輕松地編寫出各種不同的應用程序。
在Visual C++6.0中,可以利用MFC AppWizard應用程序向導快速地創建一個標準的Windows應用程序框架,只需在此基礎上添加實現特定功能的程序代碼就能編寫出相應的Windows應用程序。該應用程序框架類型中包含了三種最基本、最常用的應用程序類型:單文檔、多文檔和基于對話框的應用程序。基于對話框應用程序功能簡單、結構緊湊,執行速度快,程序源代碼少,開發調試容易,符合本課題需求,故本課題采用基于對話框應用程序。
3.2 CANUSB—Ⅰ/Ⅱ智能CAN接口卡3.2.1 產品概述CANUSB—Ⅰ/Ⅱ智能CAN接口卡兼容USB1.1和USB2.0總線,帶有1路/2路CAN接口的工業級智能型CAN數據接口卡。采用CANUSB—Ⅰ/Ⅱ智能CAN接口卡,PC可以通過USB總線連接至CAN網絡,構成實驗室、工業控制、智能小區等CAN網絡領域中數據處理、數據采集。
CANUSB—Ⅰ/Ⅱ智能CAN接口卡是CAN產品開發、CAN數據分析的強大工具;同時,具有體積小、即插即用等特點,也是便攜式系統用戶的最佳選擇。
3.2.2 智能CAN接口卡硬件接口描述CANUSB—Ⅰ/Ⅱ智能CAN接口卡集成2路CAN通道,每一路通道都是獨立的,可以用于連接一個CAN—bus網絡或者CAN—bus接口的設備。CANUSB—Ⅰ/Ⅱ智能CAN接口卡布局如下:

圖3.1 CANUSB—Ⅰ/Ⅱ智能CAN接口卡外圍端子
2路CAN—bus通道由1個10Pin接線端子引出,接線端子的引腳詳細定義如下表所示:
表3.1 CANUSB—Ⅰ/Ⅱ接口卡的CAN—bus信號分配
3.3 本章小結本章介紹了CAN總線通信系統上位機通信軟件的開發環境和CANUSB—Ⅰ/Ⅱ智能CAN接口卡。為了獲得直觀的窗口外觀,豐富、人性化的友好界面,本課題利用Visual C++6.0下的MFC類庫開發程序。
4 CAN通信軟件設計4.1 驅動程序安裝CANUSB—Ⅰ/Ⅱ智能CAN接口卡使用USB直接供電并提供智能驅動安裝包,安裝步驟如下:
點擊產品光盤的“\CANUSB\Drivers”目錄下的安裝包安裝驅動;
將CANUSB—Ⅰ/Ⅱ智能CAN接口卡通過USB電纜連接到計算機,提示發現新硬件,選擇自動安裝軟件即可。
4.2 CAN接口卡函數庫說明4.2.1 函數庫數據結構定義(1)初始化CAN數據類型
typedef struct _INIT_CONFIG
{ DWORD AccCode;//驗收碼
DWORD AccMask;//屏蔽碼
DWORD Reserved;//保留
UCHAR Filter;//濾波方式
UCHAR Baudrate;//波特率
UCHAR Mode;//模式
} VCI_INIT_CONFIG,*PVCI_INIT_CONFIG;
(2)CAN信息幀的數據類型
typedef struct _VCI_CAN_OBJ
{ BYTE CANIndex;//接受的數據幀來自哪個通道 =0時CAN0通道 =1時CAN1通道
DWORD ID;//報文ID
BYTE SendType;//發送幀類型,=0時為正常發送,=1時為自發自收,只有在此幀為發送幀時有意義。
BYTE ExternFlag;//是否是擴展幀
BYTE RemoteFlag;//是否是遠程幀
BYTE DataLen; //數據長度(<=8,即Data的長度
BYTE Data[8]; //報文的數據
}VCI_CAN_OBJ,*PVCI_CAN_OBJ;
4.2.2 接口函數說明①BOOL __stdcall VCI_OpenDevice(DWORD DevIndex);//打開設備
②BOOL __stdcall VCI_CloseDevice(DWORD DevIndex);//關閉設備
③BOOL __stdcall VCI_InitCAN(DWORD DevIndex,DWORD CANIndex,PVCI_INIT_CONFIG InitConfig);//初始化CAN
④BOOL __stdcall VCI_StartCAN(DWORD DevIndex ,DWORD CANIndex);//啟動CAN設備
⑤BOOL __stdcall VCI_ResetCAN(DWORD DevIndex ,DWORD CANIndex);//復位CAN設備
⑥BOOL __stdcall VCI_Transmit(DWORD DevIndex ,DWORD CANIndex, VCI_CAN_OBJ *SendData );//發送一幀數據
⑦DWORD __stdcall VCI_Receive(DWORD DevIndex ,PVCI_CAN_OBJ pReceive , DWORD Len , DWORD WaitTime);//接收數據
⑧BOOL __stdcall VCI_ReadDevSn(DWORD DevIndex, PCHAR DevSn);//讀取序列號
其中:
DevIndex 設備索引號,有一個設備時索引號為0,有兩個可以為0或1;
CANIndex 第幾路CAN;
InitConfig 初始化參數結構;
SendData指向信息幀結構體;
pReceive用來接收的數據幀結構體數組的首指針;
Len 讀取多少幀的數據;
WaitTime =0時為無限等待;>0時等待超時時間,以毫秒為單位;
DevSn 序列號;
返回值 為1表示操作成功,0表示操作失敗;
4.2.3 接口函數庫使用方法首先,把庫函數文件都放在工作目錄下。總共有四個文件CAN_TO_USB.h,CAN_TO_USB.lib,SiUSBXp.dll,CAN_TO_USB.dll。
VC調用動態庫的方法:
(1)在.cpp中包含CAN_TO_USB.h頭文件;
(2)在工程文件中加入CAN_TO_USB.lib文件。
4.2.4 接口函數庫使用流程
圖4.1 接口函數庫使用流程
4.3 界面設計CAN總線通信系統上位機通信軟件的設計目標是對CAN總線的運行狀態和通信能力進行有效的測試,要求能正確識別CAN設備并打開CAN通道,可封裝CAN報文進行發送,可接收CAN數據幀,并能對數據幀進行解析,在數據列表中顯示報文的相關參數信息(如:幀ID、幀格式、幀類型、DLC值以及幀數據等參數),并具有過濾功能。具體有以下幾個功能模塊:設備連接、設備啟動、設備復位、幀封裝與發送、幀接收與解析以及清除顯示。
4.3.1 界面布局設計打開MFC App Wizard(exe)創建一個基于對話框的應用程序,項目名為Test。打開對話框,按照軟件功能要求用控件編輯器添加相應控件,設置控件屬性,打開類向導,為界面上各控件添加對應的成員變量。設計完成后的界面如圖3所示。表4.1列出了CAN0通道各個控件屬性及成員變量的設置。
圖4.2 CAN總線通信系統上位機通信軟件界面設計
表4.1 CAN0通道控件屬性及成員變量的設置
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| IDC_COMBO_SENDFRAMEFORMAT0 | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
CAN1通道各個控件屬性及成員變量設置同CAN0通道,就不再贅述。
4.3.2 對話框初始化在CTestDlg類的OnInitDialog()函數中添加代碼, 在對話框初始化的時候被調用,響應WM_INITDIALOG消息,用于完成除基本的創建之外的額外的初始化工作。將額外的初始化代碼在這個函數中實現。
(1)組合框初始化
組合框的設置以控件IDC_COMBO_FILTERTYPE0為例。要求控件IDC_COMBO_FILTERTYPE0能下拉顯示兩種濾波方式:單濾波和雙濾波,默認顯示單濾波。故在OnInitDialog()函數中添加以下代碼:
//濾波方式的添加
m_ComboFilterType0.AddString("單濾波");
m_ComboFilterType0.AddString("雙濾波");
//設置第0行內容為顯示的內容,即濾波方式默認為單濾波
m_ComboFilterType0.SetCurSel(0);
其他組合框以相同方式按要求設置。
(2)編輯框初始化
編輯框的設置以控件IDC_EDIT_MASK0為例。控件IDC_EDIT_MASK0顯示的是屏蔽碼的源節點,默認顯示“ff”。故在OnInitDialog()函數中添加以下代碼:
m_EditMask0="ff";
其他編輯框以相同方式按要求設置。
(3)要求啟動時CAN默認未連接,未啟動,故在OnInitDialog()函數中添加以下代碼:
bConnectCAN=FALSE; //啟動時CAN默認未連接
bStartCAN=FALSE; //啟動時CAN默認關閉
(4)要求設備未連接時不能啟動設備,默認禁用啟動通道按鈕,故在OnInitDialog()函數中添加以下代碼:
GetDlgItem(IDC_BUTTON_CONNECT1)->EnableWindow(FALSE);
(5)更新對話框內容,把變量中的數據輸出到控件,故在OnInitDialog()函數中添加以下代碼:
UpdateData(false);
4.4 軟件功能實現4.4.1 設備連接要求點擊“連接”按鈕,上位機通信軟件與CANUSB—Ⅰ/Ⅱ智能CAN接口卡連接,并且顯示連接成功與否。若連接失敗,彈出警告框“打開設備失敗!”,若連接成功,分別在列表框IDC_LIST_INFO0和IDC_LIST_INFO1顯示“CAN0連接成功”“CAN1連接成功”。
在TestDlg.h頭文件里添加變量:
public:
int m_devnum; //設備序號
int m_cannum; //can通道編號
void CAN0ShowInfo(CString str, int code);//CAN0接收顯示控制函數
雙擊“連接”按鈕,系統自動添加消息響應函數OnButtonConnect0(),添加代碼,實現用戶單擊“連接”按鈕,完成設備的連接功能。
定義初始化CAN的數據類型的結構體:VCI_INIT_CONFIG init_config;
如果CAN已經打開,調用VCI_CloseDevice(m_devnum)函數關閉設備。調用GetCurSel()函數獲取設備序號:devnum=m_ComboDevindex.GetCurSel();
如果(VCI_OpenDevice(devnum))==0,則設備打開失敗,調用MessageBox函數彈出消息框,警告“打開設備失敗!”,否則CAN0和CAN1連接成功,分別在列表框IDC_LIST_INFO0和IDC_LIST_INFO1顯示。
此時,按鈕IDC_BUTTON_CONNECT0的標題“連接”變為“斷開”,“啟動通道”按鈕變為有效,故添加以下代碼:
GetDlgItem(IDC_BUTTON_CONNECT0)->SetWindowText("斷開");
GetDlgItem(IDC_BUTTON_CONNECT1)->EnableWindow(TRUE);

圖4.3 設備連接流程圖
4.4.2 設備啟動要求點擊“啟動通道”按鈕,CAN0通道和CAN1通道同時啟動,并顯示啟動成功與否。若啟動通道失敗,彈出消息框,發出警告,若啟動通道成功,分別在列表框IDC_LIST_INFO0和IDC_LIST_INFO1顯示“CAN0啟動成功”“CAN1啟動成功”。
雙擊“啟動通道”按鈕,系統自動添加消息響應函數OnButtonConnect1(),添加代碼,實現用戶單擊“啟動通道”按鈕,完成通道CAN0和CAN1的啟動功能。
如果VCI_InitCAN(m_devnum,0,&init_config)!=true,則通道CAN0初始化失敗,如果VCI_InitCAN(m_devnum,1,&init_config)!=true,則通道CAN1初始化失敗,并立即調用VCI_CloseDevice(m_devnum)函數,關閉設備
如果VCI_StartCAN(m_devnum,0)!=true,則通道CAN0啟動失敗,如果VCI_StartCAN(m_devnum,1)!=true,則通道CAN1啟動失敗,并立即調用VCI_CloseDevice(m_devnum)函數,關閉設備。如果通道CAN0和CAN1啟動成功,則禁用啟動通道按鈕:
GetDlgItem(IDC_BUTTON_CONNECT1)->EnableWindow(FALSE);

圖4.4 設備啟動流程圖
4.4.3 設備復位要求點擊“復位CAN0”按鈕,復位通道CAN0,點擊“復位CAN1”按鈕,復位通道CAN1,成功則分別在列表框IDC_LIST_INFO0和IDC_LIST_INFO1顯示“復位成功”,失敗則列表框IDC_LIST_INFO0和IDC_LIST_INFO1顯示“復位失敗”。
CAN0通道:
雙擊“復位CAN0”按鈕,系統自動添加消息響應函數OnButtonResetcan0(),添加代碼,實現用戶單擊“復位CAN0”按鈕,完成通道CAN0的復位功能。
如果VCI_ResetCAN(m_devnum,0)==1,則復位成功,否則,復位失敗,將結果顯示在列表框IDC_LIST_INFO0內。
CAN1通道的復位功能設置如CAN0通道,在此就不再贅述。

圖4.5 CAN0通道復位流程圖
4.4.4 幀封裝與發送(1)幀封裝
報文標識符指定了數據通訊中的源節點 MACID 和目標節點MACID,并指示了報文的功能以及所要訪問的資源節點。報文標識符被分為SrcMACID (源節點地址)、DestMACID(目標節點地址)、ACK 位、FuncID(功能碼)和Source ID(資源節點地址)5 個部分,如表4.2示。
表4.2 iCAN標識符分配
SrcMACID (源節點地址):發送iCAN 報文的節點地址,占用標識符位ID28~ID21,SrcMACID 的高2 位固定為0,數值范圍為0x00-0x3F。
DestMACID (目標節點地址):接收iCAN 報文節點地址,占用標識符位ID20~ID13,DestMACID 的高2 位固定為0,數值范圍為0x00-0x3F。當DestMACID 的值為0xFF時,表示本次發送的幀是廣播幀。
ACK(相應標識符):分配1 位,占用標識符位ID12。該位用于區分幀類型為命令幀還是響應幀,并說明是否需要應答本幀。
表4.3相應標志位
| |
| 用于命令幀,本幀需要應答,但對于廣播幀,此值無意義 |
| 用于響應幀,本幀不需要應答;或不需要應答的命令幀(如廣播幀) |
FunctionID(功能碼):分配4 位,占用標識符位ID11~ID8,功能碼用于指示iCAN 報文需要實現的功能,接收報文的節點根據報文中的功能碼進行相應的處理。
Source ID(資源節點地址):用于指示所要訪問的從站內部資源的起始地址,分配8 位,占用標識符位ID7~ID0。
分別輸入源節點、目的節點、響應標示符、功能碼、資源節點地址,要求對報文進行封裝后發送。
以源節點為例,占用標識符位ID28~ID21,故處理程序如下:
memcpy(&szFrameID[0],(LPCTSTR)m_EditSendFrmID0,m_EditSendFrmID0.GetLength());//拷貝m_EditSendFrmID0所指內存內容到&szFrameID[0]所指的內存地址上
CAN0strtodata((unsigned char*)szFrameID,&FrameID[0],1,0);//字符串轉換為數據串
ExtendID |= (FrameID[0]&0x3f)<<21;//左移21位
其他以相同方式處理,報文就封裝在FrameID[0]中。
(2)發送
要求點擊“發送”按鈕,發送數據,結果分別顯示在列表框IDC_LIST_INFO0和IDC_LIST_INFO1內。
CAN0通道:
雙擊“發送”按鈕,系統自動添加消息響應函數OnButtonSend0(),添加代碼,實現用戶單擊“發送”按鈕,完成發送通道CAN0數據的功能。
如果bStartCAN==FALSE,則通道未啟動,不能發送數據,彈出消息框,警告“請啟動設備!”。
調用VCI_Transmit(m_devnum,0,&frameinfo)函數判斷發送狀態,如果為真,則發送成功,在列表框IDC_LIST_INFO0內顯示封裝好的幀ID和“設備0 通道CAN0 發送成功”,否則顯示“設備0 通道CAN0 發送失敗”。
CAN1通道的發送功能設置同CAN0通道,在此就不再贅述。

圖4.6 CAN0通道發送流程
4.4.5 幀接收與解析(1)接收
要求CAN0和CAN1通道能接收到對方通道或自己發出的數據。
CAN0通道:
在TestDlg.h頭文件里定義CAN0接收線程執行函數:
static UINT CAN0ReceiveThread(void *param);
在TestDlg.cpp內添加CAN0接收線程執行函數
UINT CTestDlg::CAN0ReceiveThread(void *param){}并在其中添加代碼,完成數據接收功能。
定義CAN信息幀數據類型的結構體:VCI_CAN_OBJ frameinfo[50];
獲取序列號:bSn=VCI_ReadDevSn(dlg->m_devnum,DevSn);
獲取數據長度:Len=VCI_Receive(dlg->m_devnum,frameinfo,50,200);
如果Len<=0,則沒有接收到數據,否則,接收到數據。
如果frameinfo.CANIndex==0,則CAN0通道接收數據,否則,CAN1通道接收數據。如果frameinfo.ExternFlag==0,則幀類型為標準幀,否則,為擴展幀。如果frameinfo.RemoteFlag==0,則幀格式為數據幀,否則,為遠程幀。

圖4.7 CAN0接收數據流程圖
(2)幀解析
- 源節點:封裝后的幀ID右移21位輸出的即為源節點,程序如下:
tmpstr.Format("源節點:%02x ",(frameinfo.ID>>21)&0x3f);
- 目的節點:封裝后的幀ID右移13位輸出的即為目的節點,程序如下:
tmpstr.Format(" 目的節點:%02x ",(frameinfo.ID>>13)&0x3f);
- 響應標示符:封裝后的幀ID右移12位輸出的即為響應標示符,如果為1則為響應幀,為0則為命令幀,程序如下:
if((frameinfo.ID>>12)&0x01)
str+=" 響應幀";
else
str+=" 命令幀";
- 功能碼:封裝后的幀ID右移8位輸出的即為功能碼,程序如下:
tmpstr.Format(" function ID:%02x ",(frameinfo.ID>>8)&0x0f);
- 資源節點編號:封裝后的幀ID最后8位即為功能碼,程序如下:
tmpstr.Format(" source ID:%02x ",frameinfo.ID&0xff);
圖4.8 幀解析效果圖
4.4.6 清除顯示要求點擊“清除顯示”按鈕,列表框IDC_LIST_INFO0和IDC_LIST_INFO1內的內容全部清除。
CAN0通道:
雙擊“清除顯示”按鈕,系統自動添加消息響應函數OnButton Clear0(),添加代碼,實現用戶單擊“清除顯示”按鈕,完成列表框IDC_LIST_INFO0內的內容全部清除功能。
添加以下代碼,清除CAN0列表顯示項:
m_ListInfo0.ResetContent();
4.5 本章小結本章具體介紹了CAN通信軟件的設計,第一部分介紹了CANUSB—Ⅰ/Ⅱ智能CAN接口卡的驅動安裝方法;第二部分介紹了CAN接口卡函數庫;第三部分介紹了軟件的界面設計,包括界面的布局、控件屬性及成員變量的設置,和對話框的初始化;第四部分詳細介紹了軟件功能的實現,包括設備連接、啟動、復位、幀封裝與發送、幀接收與解析和清除顯示六個部分功能的實現方法。
5 測試及發布5.1 軟件功能測試將CANUSB—Ⅰ/Ⅱ智能CAN接口卡連至PC的USB接口槽,運行上位機軟件,測試功能。
5.1.1 基本功能測試執行程序,如圖輸入數據,測試各項功能是否能正常運行。

圖5.1 程序軟件功能測試
經測試,各項功能運行正常。
5.1.2 非法輸入限制對于編輯框,若輸入非法字符,則彈出消息框“非法字符,請重新輸入!”的警告,如下圖所示:

圖5.2 非法輸入警告
5.2 程序發布一個程序除了.exe以外,還需要用到很多其他外部資源,這樣程序使用起來很不方便,程序打包就是將這些所有資源放到一個安裝程序中,這樣只要下載并運行這個安裝程序,就可以讓安裝程序釋放目標程序及所有這些資源,方便使用。
Inno Setup是一個免費的安裝制作軟件,小巧、簡便、精美是其最大的特點。用Inno Setup對已經制作好的工程進行打包步驟如下:
- 將已經調試完成的工程,生成發行版(release);
- 安裝好Inno Setup Compiler漢化版,啟動軟件,使用腳本設計向導創建一個新的腳本文件,完成安裝程序的制作,過程如下圖所示:

圖5.3 應用程序信息

圖5.4 應用程序文件夾

圖5.5 應用程序文件

圖5.6 應用程序圖標

圖5.7 應用程序文檔

圖5.8 安裝語言

圖5.9 編譯設置

圖5.10 Inno Setup 預處理器

圖5.11 完成向導

圖5.12 編譯腳本
- 雙擊Setup圖標,進行嘗試安裝,安裝成功后,在開始菜單欄出現運行和卸載快捷方式,可以運行軟件和卸載軟件。

圖5.13 安裝成功效果圖
5.3 本章小結本章對已經編寫完成的程序進行功能測試,主要測試連接設備、啟動通道、復位、發送和接收功能,并能實現幀的封裝和解析,測試無誤后進行程序發布,方便使用。
結論
畢業設計是本科學習階段一次非常難得的理論與實際相結合的機會,通過這次CAN總線通信系統上位機通信軟件的設計,我從對CAN總線相關技術一無所知到有了一點了解,鞏固了曾經學過的知識,鍛煉了理論與實際結合解決實際問題的能力,同時也提高了我查閱文獻資料的能力,使自己有了全方位的提高,豐富了自己的經驗。
本文主要完成了以下的研究:
1、對CAN總線的研究背景、發展現狀及本課題的研究目的和意義進行了論述。
2、簡單分析了CAN2.0協議和CAN控制器SJA1000。
3、介紹了本課題的開發環境和CANUSBⅠ/Ⅱ只能CAN接口卡。
4、基于VC++設計CAN通信軟件,并實現了以下功能:
①正確識別CAN設備并打開CAN通道;
②可封裝CAN報文進行發送;
③可接收CAN數據幀,并能對接收的數據幀進行解析:在數據列表中顯示報文的相關參數信息(如:幀ID、幀格式、幀類型、DLC值以及幀數據等參數);
④具有過濾功能,可不顯示指定的協議幀。
5、對軟件功能進行測試,并發布軟件。
由于自身水平所限,畢業設計必定還有很多不足和欠缺考慮的地方,也感到自身知識的貧乏,希望在日后的努力中能夠更加完善。
致謝
本人的畢業設計一直是在李艷老師的悉心指導下進行的。李老師治學嚴謹,要求嚴格,學識淵博,為人親切。從課題的選定、方案的確定、實際的設計到論文的寫作,李老師都給予了無微不至的關懷。在整個畢業設計過程中,李艷老師時時以高標準要求,嚴格安排時間,并為我指明大方向,使我少走很多彎路。在遇到問題時,李艷老師也耐心指導,循循善誘,讓我能夠獨立思考,順利地完成我的畢業設計。在此表示誠摯的感謝和由衷的敬意。
此外,我還要感謝許多同學在整個過程中的幫助和配合。
最后,再次對關心、幫助我的老師同學表示衷心的感謝!
完整的Word格式文檔51黑下載地址:
CAN總線通信系統上位機通信軟件的設計.doc
(842 KB, 下載次數: 113)
2018-8-2 14:52 上傳
點擊文件名下載附件