基本功能
在本設(shè)計中,數(shù)據(jù)的處理可以使用PC機的MATLAB等功能強大的軟件,但是這類現(xiàn)有的數(shù)據(jù)處理軟件并不能對特有的數(shù)據(jù)采集系統(tǒng)的下位機采集模塊進(jìn)行直接控制,因此需要針對特定的數(shù)據(jù)采集系統(tǒng)編寫對應(yīng)的上位機軟件,上位機軟件是針對上述目的而設(shè)計與編寫的,是整個采集系統(tǒng)的控制前端和數(shù)據(jù)存儲及處理中心??刂乒δ苤饕刂葡挛粰C采集的開始與終止,采集的頻率等,數(shù)據(jù)處理功能主要包括繪制波形圖,將數(shù)據(jù)顯示于列表,將數(shù)據(jù)存儲于文件,其中將數(shù)據(jù)存儲于文件將便于使用現(xiàn)有的數(shù)據(jù)處理軟件對數(shù)據(jù)進(jìn)行一些數(shù)值算法處理,以達(dá)到科學(xué)研究,結(jié)論驗證等目的。
開發(fā)環(huán)境
C++程序設(shè)計語言可以很好地實現(xiàn)面向?qū)ο蟮?a target="_blank">編程思想,采用C++編寫上位機程序,可以將每一個功能模塊封裝成一個類,修改某個類的實現(xiàn),增加類的功能不會影響整個程序的框架,這樣就很容易維護(hù)和擴展功能;加之我們要實現(xiàn)的軟件功能中需要調(diào)用大量的windows API函數(shù)庫,所以采用VC++6.0作為上位機的開發(fā)環(huán)境。
程序功能模塊劃分
總的功能模塊主要包括三個模塊,即HID設(shè)備讀寫模塊,數(shù)據(jù)采集模塊,數(shù)據(jù)處理模塊。
HID設(shè)備的查找與讀寫
(1)枚舉
USB主機在檢測到USB設(shè)備插入后,就要對設(shè)備進(jìn)行枚舉了。枚舉就是從設(shè)備讀取一些信息,知道設(shè)備是什么樣的設(shè)備,如何進(jìn)行通信,這樣主機就可以根據(jù)這些信息來加載合適的驅(qū)動程序。
(2)HID
人機接口設(shè)備(HID)是指直接和人進(jìn)行互動的設(shè)備,如鼠標(biāo)、鍵盤等。 在Windows 中,具有相似屬性和提供相似服務(wù)的設(shè)備被歸為一種設(shè)備類型,一種類型的設(shè)備可以使用一個通用的設(shè)備驅(qū)動程序。 在運行Windows 98 或更高版本的PC 機上,應(yīng)用程序可以使用操作系統(tǒng)內(nèi)置的HID 類驅(qū)動程序與HID 通信。 這樣使得符合HID 類的USB 設(shè)備很容易開發(fā)與運行。
(3)HID設(shè)備的查找
在Windows操作系統(tǒng)中內(nèi)置很多與HID有關(guān)的API函數(shù),調(diào)用這些函數(shù),就可以開始對指定的HID設(shè)備進(jìn)行查找,查找HID設(shè)備的最終目的是獲得該設(shè)備的路徑名,設(shè)備的存取容量等信息,為以后對該設(shè)備進(jìn)行讀寫做好準(zhǔn)備。
(4)HID設(shè)備的讀寫
在取得了HID設(shè)備的路徑全面后,即可開始對HID設(shè)備進(jìn)行讀寫,對設(shè)備的讀寫也是通過調(diào)用相應(yīng)的函數(shù)來實現(xiàn)的。
控制下位機進(jìn)行數(shù)據(jù)采集
上位機向下位機發(fā)送命令,控制下位機進(jìn)行數(shù)據(jù)采集,并從下位機獲取數(shù)據(jù),在這個過程中,要處理好兩個線程的同步的問題,即數(shù)據(jù)采集線程和數(shù)據(jù)處理線程能夠協(xié)調(diào)工作,保正系統(tǒng)能正確穩(wěn)定的工作。具體的解決方法是實現(xiàn)對某些數(shù)據(jù)訪問的原子操作,即一個線程在對公共數(shù)據(jù)進(jìn)行訪問時,另一個線程不能打擾,直到操作線程操作完成,放棄對數(shù)據(jù)的使用權(quán),另一個線程才能夠訪問數(shù)據(jù)。
下位機獲取了關(guān)于采集的有關(guān)參數(shù)后,即可開始采集,每隔一定時間采集一個數(shù)據(jù),當(dāng)采集數(shù)據(jù)數(shù)目達(dá)到限制值個數(shù)后,本次采集完成,此時下位機才開始將采集數(shù)據(jù)發(fā)送給上位機。
上位機對采集的數(shù)據(jù)的處理
上位機在將數(shù)據(jù)采集命令發(fā)送給下位機后,所要做的就是等待下位機采集完成并接收數(shù)據(jù),因此上位機將循環(huán)查詢下位機工作狀態(tài),一旦檢測到下位機采集結(jié)束的標(biāo)志,上位機就開始對數(shù)據(jù)進(jìn)行處理。
數(shù)據(jù)處理分為三種:
(1)繪制波形圖
繪制波形圖的要求有兩點:第一是不能頻繁閃爍,影響觀察;二是波形圖是動態(tài)的,因為繪制區(qū)域有限,而所采集的數(shù)據(jù)是源源不斷增加的,因此要求波形圖能夠動態(tài)的更新。
(2)添加到列表顯示
可直觀地查看目前所采集的所有數(shù)據(jù)。
(3)保存到文件
運用功能強大的數(shù)據(jù)處理軟件對數(shù)據(jù)進(jìn)行更深的處理。
界面顯示
采集單極性正弦波工作界面
代碼:
1 HID設(shè)備通信模塊實現(xiàn)代碼/*hid.h頭文件*/
2 #ifndef HID_H
3 #define HID_H
4 #include
5 #include
6 #include
7 #include “commonuse.h”
8 using std::string;
9 #pragma comment( lib, “setupapi.lib” )
10 extern “C” {
11 #include “hidsdi.h”
12 }
13 #pragma comment( lib, “hid.lib” )
14
15
16 class Hid
17 {
18
19 public:
20 Hid(const string &DeviceIdStr = MY_DEVICE_ID);
21 //Hid(DWORD Vid, DWORD Pid) {}
22 ~Hid() ;
23 BOOL Connect() ;
24 //BOOL ChangeDevice() {}
25 BOOL WriteHid(const BYTE * WriteBuff);
26 BOOL ReadHid(BYTE * ReadBuff);
27 BOOL IsWriteValid() const { return m_WriteValid ; }
28 BOOL IsReadValid() const { return m_ReadValid ; }
29 BOOL IsConnected() const { return m_IsConnected; }
30 const string & GetDeviceIDDesc() const { return m_DeviceIdStr ;}
31 private:
32 BOOL GetWRHandle() ;
33 private:
34 HANDLE m_WriteHandle;
35 HANDLE m_ReadHandle ;
36 string m_DeviceIdStr;//設(shè)備描述字符串
37 DWORD m_PID;
38 DWORD m_VID;
39 BOOL m_IsConnected ;//是否已連接上
40 BOOL m_ReadValid;//是否可進(jìn)行讀操作
41 BOOL m_WriteValid;//是否可進(jìn)行寫操作
42 BYTE m_RWBuff[USB_BUFF_SIZE+1] ;//讀寫緩沖
43
44
45 } ;
46
47
48
49 #endif
50
51
52 /*hic.cpp源文件*/
53
54 #include “Hid.h”
55
56 Hid::Hid(const string &DeviceIdStr):
57 m_DeviceIdStr(DeviceIdStr)
58 {
59
60 m_WriteHandle = INVALID_HANDLE_VALUE ;
61 m_ReadHandle = INVALID_HANDLE_VALUE ;
62 m_PID = 0;
63 m_VID = 0;
64 m_IsConnected = FALSE ;
65 m_ReadValid = FALSE ;
66 m_WriteValid = FALSE;
67 strcpy((char *)m_RWBuff,“”) ;
68 }
69
70 BOOL Hid::GetWRHandle()
71 {
72 GUID InterfaceClassGuid =
73 {0x4d1e55b2, 0xf16f, 0x11cf, 0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30};
74 HDEVINFO DeviceInfoTable = INVALID_HANDLE_VALUE;
75 PSP_DEVICE_INTERFACE_DATA InterfaceDataStructure = new SP_DEVICE_INTERFACE_DATA;
76 PSP_DEVICE_INTERFACE_DETAIL_DATA DetailedInterfaceDataStructure = new SP_DEVICE_INTERFACE_DETAIL_DATA;
77 SP_DEVINFO_DATA DevInfoData;
78
79 DWORD InterfaceIndex = 0;
80 DWORD StatusLastError = 0;
81 DWORD dwRegType;
82 DWORD dwRegSize;
83 DWORD StructureSize = 0;
84 PBYTE PropertyValueBuffer;
85 bool MatchFound = false;
86 DWORD ErrorStatus;
87 DeviceInfoTable = SetupDiGetClassDevs(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT “ DIGCF_DEVICEINTERFACE);
88 while(true)
89 {
90 InterfaceDataStructure-》cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
91 if(SetupDiEnumDeviceInterfaces(DeviceInfoTable, NULL, &InterfaceClassGuid, InterfaceIndex, InterfaceDataStructure))
92 {
93 ErrorStatus = GetLastError();
94 if(ERROR_NO_MORE_ITEMS == ErrorStatus)
95 {
96 SetupDiDestroyDeviceInfoList(DeviceInfoTable);
97 return FALSE;
98 }
99 }
100 else
101 {
102
103 ErrorStatus = GetLastError();
104 SetupDiDestroyDeviceInfoList(DeviceInfoTable);
105 return FALSE;
106 }
107
108 DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
109 SetupDiEnumDeviceInfo(DeviceInfoTable, InterfaceIndex, &DevInfoData);
110
111 SetupDiGetDeviceRegistryProperty(DeviceInfoTable, &DevInfoData, SPDRP_HARDWAREID, &dwRegType, NULL, 0, &dwRegSize);
112 Pr
責(zé)任編輯;zl
評論
查看更多