markmin214

基本功能

  在本设计中,数据的处理可以使用PC机的MATLAB等功能强大的软件,但是这类现有的数据处理软件并不能对特有的数据采集系统的下位机采集模块进行直接控制,因此需要针对特定的数据采集系统编写对应的上位机软件,上位机软件是针对上述目的而设计与编写的,是整个采集系统的控制前端和数据存储及处理中心。控制功能主要包括控制下位机采集的开始与终止,采集的频率等,数据处理功能主要包括绘制波形图,将数据显示于列表,将数据存储于文件,其中将数据存储于文件将便于使用现有的数据处理软件对数据进行一些数值算法处理,以达到科学研究,结论验证等目的。

开发环境

  C++程序设计语言可以很好地实现面向对象的编程思想,采用C++编写上位机程序,可以将每一个功能模块封装成一个类,修改某个类的实现,增加类的功能不会影响整个程序的框架,这样就很容易维护和扩展功能;加之我们要实现的软件功能中需要调用大量的windows API函数库,所以采用VC++6.0作为上位机的开发环境。

程序功能模块划分

  总的功能模块主要包括三个模块,即HID设备读写模块,数据采集模块,数据处理模块。

HID设备的查找与读写

(1)枚举

USB主机在检测到USB设备插入后,就要对设备进行枚举了。枚举就是从设备读取一些信息,知道设备是什么样的设备,如何进行通信,这样主机就可以根据这些信息来加载合适的驱动程序。

(2)HID

人机接口设备(HID)是指直接和人进行互动的设备,如鼠标、键盘等. 在Windows 中,具有相似属性和提供相似服务的设备被归为一种设备类型,一种类型的设备可以使用一个通用的设备驱动程序. 在运行Windows 98 或更高版本的PC 机上,应用程序可以使用操作系统内置的HID 类驱动程序与HID 通信. 这样使得符合HID 类的USB 设备很容易开发与运行.

(3)HID设备的查找

在Windows操作系统中内置很多与HID有关的API函数,调用这些函数,就可以开始对指定的HID设备进行查找,查找HID设备的最终目的是获得该设备的路径名,设备的存取容量等信息,为以后对该设备进行读写做好准备.

 

(4)HID设备的读写

在取得了HID设备的路径全面后,即可开始对HID设备进行读写,对设备的读写也是通过调用相应的函数来实现的。

控制下位机进行数据采集

  上位机向下位机发送命令,控制下位机进行数据采集,并从下位机获取数据,在这个过程中,要处理好两个线程的同步的问题,即数据采集线程和数据处理线程能够协调工作,保正系统能正确稳定的工作。具体的解决方法是实现对某些数据访问的原子操作,即一个线程在对公共数据进行访问时,另一个线程不能打扰,直到操作线程操作完成,放弃对数据的使用权,另一个线程才能够访问数据。

  下位机获取了关于采集的有关参数后,即可开始采集,每隔一定时间采集一个数据,当采集数据数目达到限制值个数后,本次采集完成,此时下位机才开始将采集数据发送给上位机。

 

上位机对采集的数据的处理

  上位机在将数据采集命令发送给下位机后,所要做的就是等待下位机采集完成并接收数据,因此上位机将循环查询下位机工作状态,一旦检测到下位机采集结束的标志,上位机就开始对数据进行处理。

数据处理分为三种:

(1)绘制波形图

绘制波形图的要求有两点:第一是不能频繁闪烁,影响观察;二是波形图是动态的,因为绘制区域有限,而所采集的数据是源源不断增加的,因此要求波形图能够动态的更新。

(2)添加到列表显示

可直观地查看目前所采集的所有数据。

(3)保存到文件

   运用功能强大的数据处理软件对数据进行更深的处理。

界面显示

  采集单极性正弦波工作界面

  代码:    

Code
  1 HID设备通信模块实现代码/*hid.h头文件*/
  2 #ifndef HID_H
  3 #define HID_H
  4 #include <windows.h>
  5 #include <setupapi.h>
  6 #include <string>
  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;//设备描述字符串
 37     DWORD m_PID;
 38     DWORD m_VID;
 39     BOOL m_IsConnected ;//是否已连接上
 40     BOOL m_ReadValid;//是否可进行读操作
 41     BOOL m_WriteValid;//是否可进行写操作
 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             PropertyValueBuffer = (BYTE *) malloc (dwRegSize);
113         
114             if(PropertyValueBuffer == NULL)    
115             {
116                 SetupDiDestroyDeviceInfoList(DeviceInfoTable);    
117                 return FALSE;        
118             }
119 
120             SetupDiGetDeviceRegistryProperty(DeviceInfoTable, &DevInfoData, SPDRP_HARDWAREID, &dwRegType, PropertyValueBuffer, dwRegSize, NULL);
121             MatchFound =( strcmp(m_DeviceIdStr.c_str(),(char *)PropertyValueBuffer) == 0 );
122             free(PropertyValueBuffer);
123 
124             //如果找到设备
125             if(MatchFound == true)
126             {
127 
128                 DetailedInterfaceDataStructure->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
129                 SetupDiGetDeviceInterfaceDetail(DeviceInfoTable, InterfaceDataStructure, NULL, NULL, &StructureSize, NULL);    
130                 DetailedInterfaceDataStructure = (PSP_DEVICE_INTERFACE_DETAIL_DATA)(malloc(StructureSize));    
131                 if(DetailedInterfaceDataStructure == NULL)
132                 {
133                     SetupDiDestroyDeviceInfoList(DeviceInfoTable);    
134                     return FALSE;        
135                 }
136                 DetailedInterfaceDataStructure->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
137                 SetupDiGetDeviceInterfaceDetail(DeviceInfoTable, InterfaceDataStructure, DetailedInterfaceDataStructure, StructureSize, NULL, NULL); 
138 
139                 m_WriteHandle =  CreateFile((DetailedInterfaceDataStructure->DevicePath),\
140                        GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0) ;
141             
142             
143                 ErrorStatus = GetLastError();
144                 if(ErrorStatus != ERROR_SUCCESS)
145                 {
146                         return FALSE;
147                 }    
148                 m_ReadHandle = CreateFile((DetailedInterfaceDataStructure->DevicePath), \
149                     GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0) ;
150                 ErrorStatus = GetLastError();
151                 if(ErrorStatus != ERROR_SUCCESS)
152                 {
153                     return FALSE ;
154                 }
155 
156                 free(DetailedInterfaceDataStructure) ;
157                 SetupDiDestroyDeviceInfoList(DeviceInfoTable);    
158                 return TRUE;
159             } 
160 
161             InterfaceIndex++;    
162         }    
163 }
164 BOOL Hid::Connect()
165 {    
166     if(GetWRHandle())
167     {
168         m_IsConnected = TRUE ;
169         m_WriteValid = m_WriteHandle == INVALID_HANDLE_VALUE ? FALSE:TRUE ;
170         m_ReadValid  = m_ReadHandle  == INVALID_HANDLE_VALUE ? FALSE:TRUE ;
171         return TRUE ;
172     }
173     return FALSE;
174 }
175 
176 BOOL Hid::WriteHid(const BYTE * WriteBuff)
177 {        
178     DWORD WriteNum = 0 ;
179     m_RWBuff[0] = 0x00 ;
180     memcpy(m_RWBuff + 1, WriteBuff, USB_BUFF_SIZE) ;
181     if(!WriteFile(m_WriteHandle,m_RWBuff, USB_BUFF_SIZE + 1, & WriteNum, NULL))
182     {
183         return FALSE ;
184     }
185     return TRUE;
186 }
187 
188 BOOL Hid::ReadHid(BYTE * ReadBuff)
189 {
190     DWORD ReadNum = 0 ;
191     if(!ReadFile(m_ReadHandle, m_RWBuff, USB_BUFF_SIZE + 1, &ReadNum, NULL))
192     {
193         return FALSE ;
194     }
195     memcpy(ReadBuff, m_RWBuff + 1, USB_BUFF_SIZE );
196     return TRUE ;
197 
198 }
199 Hid::~Hid()
200 {
201     m_WriteHandle == INVALID_HANDLE_VALUE ? NULL : CloseHandle(m_WriteHandle);
202     m_ReadHandle  == INVALID_HANDLE_VALUE ? NULL : CloseHandle(m_ReadHandle);
203 }
204 
205  数据采集模块实现代码
206 /*datacollectthread.h*/
207 #ifndef COLLECT_THREAD_H
208 #define COLLECT_THREAD_H
209 
210 #include "commonuse.h"
211 #include "hid.h"
212 #include <process.h>
213 #include <math.h>
214 class DataCollectThread
215 {
216 public:
217     DataCollectThread() {};
218     ~DataCollectThread() {};
219 
220     void StartThread(COLLECTED_DATA *p_collectedData) 
221     {
222         p_collectedData->classPointer = (void *)this ;
223         _beginthread(BeginCollectTemp, 0 , p_collectedData) ;
224     }
225     static void BeginCollectTemp(void *p_collectedData) 
226     {
227         DataCollectThread *thisPointer ;
228         thisPointer =  ( (DataCollectThread *)(((COLLECTED_DATA *)p_collectedData)->classPointer) ) ;
229          thisPointer -> BeginCollect( (COLLECTED_DATA *) p_collectedData );
230     }
231     //void EndThread() ;
232 private:
233     void BeginCollect(COLLECTED_DATA *p_collectedData) ;
234 private:
235     void GetData(COLLECTED_DATA *p_collectedData,collect_t *dataBuff, BYTE wantNum) ;
236 
237     BOOL SendCommand(Hid *myHid, BYTE *commandBuff ) ;
238     BOOL GetPicState(Hid *myHid, BYTE *stateBuff   ) ;
239     BOOL ReceiveData(Hid *myHid, BYTE *dataBuff    ) ;
240 
241 } ;
242 #endif
243 /*datacollectthread.cpp*/
244 #include "datacollectthread.h"
245 
246 void DataCollectThread::BeginCollect(COLLECTED_DATA * p_collectedData)
247 {
248     collect_t collectBuff[USB_BUFF_SIZE] = {0x00} ;
249 
250     
251     
252         //等待公共数据缓冲区可写
253         while(1)
254         {
255         //    ADD_STRING_TO_EDIT(p_collectedData->hWorkState, "采集线程尝试进入缓冲区...\n") ;
256                 InitializeCriticalSection(  &p_collectedData->criticalSection ) ;
257                 EnterCriticalSection(  &p_collectedData->criticalSection );
258 
259                 //    ADD_STRING_TO_EDIT(p_collectedData->hWorkState, "采集线程进入缓冲区...\n") ;
260             //放入数据
261                 if(p_collectedData ->canBeWriting)
262                 {
263                     ADD_STRING_TO_EDIT(p_collectedData->hWorkState, "开始数据采集...\n") ;
264                     //采集数据
265                     GetData(p_collectedData, collectBuff, p_collectedData->picCollectNum) ;
266                     ADD_STRING_TO_EDIT(p_collectedData->hWorkState, "数据采集结束,正在保存到公共缓冲区...\n") ;
267                     memcpy(p_collectedData->data , collectBuff , p_collectedData->picCollectNum * 2 * sizeof(BYTE) ) ;
268                     p_collectedData->canBeReading = TRUE ;
269                     p_collectedData ->canBeWriting = FALSE ;
270                     if(p_collectedData->collectMode == AUTO_COLLECT)
271                     {
272                         if(p_collectedData->endCollect)
273                         {
274                             p_collectedData->endCollect = FALSE ;
275                             break ;
276                         }
277                     //    goto NEXT ;
278                     }
279                     else
280                     {
281                         break ;
282                     }
283 
284                 
285                 }
286                 LeaveCriticalSection(&p_collectedData->criticalSection) ;
287                 Sleep(300) ;
288         }
289 END:
290     ADD_STRING_TO_EDIT(p_collectedData->hWorkState, "采集线程退出...\n") ;
291 
292     SendMessage(p_collectedData->hDlg, WM_END_COLLECT, 0, 0 ) ;
293     return ;
294 }
295 
296 collect_t get_rand()
297 {
298     return 0x294 ;
299 }
300 
301 void DataCollectThread::GetData(COLLECTED_DATA *p_collectedData,collect_t *dataBuff, BYTE wantNum)
302 {
303 
304      BYTE COMMAND[USB_BUFF_SIZE] = {0x90,((p_collectedData->picCollectTimeGap) >> 24 ) & 0xff ,
305                                           ((p_collectedData->picCollectTimeGap) >> 16 ) & 0xff ,         
306                                           ((p_collectedData->picCollectTimeGap) >> 8 ) & 0xff ,
307                                           ((p_collectedData->picCollectTimeGap) ) & 0xff ,
308                                          wantNum
309     
310     } ;
311      BYTE  stateBuff[USB_BUFF_SIZE] =  {0} ;
312 
313 #if 1
314 
315     //发送命令,采集开始(1 BYTE)+采集时间间隔(4 BYTES)+采集数目(1 BYTE)
316      if(! SendCommand(p_collectedData->p_myHid, COMMAND) )
317      {
318         
319      }
320     //循环查询下位机是否采集结束,0x91为采集结束标志,其后跟着所采集数据
321     while( GetPicState(p_collectedData->p_myHid , stateBuff) , !(stateBuff[0] == 0x91 && stateBuff[1] == 0x91 ) )
322         NULL ;
323 
324     memcpy(dataBuff,stateBuff+2, (wantNum * 2 *sizeof(BYTE))) ;
325 
326 #endif
327 
328 
329 #if 0
330     static double x = 0 ;
331     int i = 0; 
332     WORD *tmpPtr = (WORD *)stateBuff ;
333     for(i = 0 ; i < wantNum; ++ i)
334     {
335         tmpPtr[i] =  abs( 5.0*sin(x++) );
336     //    x+=0.1;
337     }
338 
339     memcpy(dataBuff,stateBuff, (wantNum * 2 *sizeof(BYTE))) ;
340 
341 #endif
342 
343 }
344 
345 BOOL DataCollectThread::SendCommand(Hid *myHid, BYTE *commandBuff ) 
346 {
347  return myHid->WriteHid(commandBuff) ;
348 }
349 BOOL DataCollectThread::GetPicState(Hid *myHid, BYTE *statedBuff)
350 {
351     return myHid->ReadHid(statedBuff) ;
352 }
353 
354 BOOL DataCollectThread::ReceiveData(Hid *myHid, BYTE *dataBuff ) 
355 {
356 
357     return myHid->ReadHid(dataBuff) ;
358 }
上位机数据处理模块实现代码
360 /**datadealthresd.h/
361 #ifndef DRAW_THREAD
362 #define DRAW_THREAD
363 
364 #include "commonuse.h"
365 #include "draw.h"
366 #include <windows.h>
367 #include <process.h>
368 #include <string>
369 #include <math.h>
370 #include <commctrl.h>
371 using std::string ;
372 
373 
374 #define  TO_REAL_DATA(data) ( (double)((data)/(1023.0) * (5.0) ) )
375 
376 class DataDealThread//数据处理线程类
377 {
378 
379 public:
380     DataDealThread() { }
381     ~DataDealThread() {  DeleteDC(m_drawData.m_memDc) ;
382                          DeleteDC(m_drawData.m_screenDc) ;
383                          DeleteObject(m_drawData.m_hBitMap ) ;
384                         } 
385 
386     void StartThread(DEAL_DATA *p_dealData) 
387     {
388         p_dealData->dealClassPointer = (void *)this ;
389         _beginthread(StartDealTmp, 0, (void *)p_dealData) ;
390     }
391     void EndDealThread()  ;
392         enum {MAX_BUFF_NUM = 100} ;
393 private:
394     static void StartDealTmp(void *p_dealData) 
395     {
396         DataDealThread *thisPointer ;
397         DEAL_DATA *k = (DEAL_DATA *)p_dealData ;
398 
399         thisPointer = (DataDealThread *) ( (DEAL_DATA *)p_dealData)->dealClassPointer ;//p_collectedData->classPointer ;
400         thisPointer->StartDeal((DEAL_DATA *)p_dealData) ;
401     }
402 private: 
403     void StartDeal( DEAL_DATA *p_dealData)  ; 
404 private:
405     void DataInit(const DEAL_DATA *p_dealData) ;
406     void DrawInit() ;
407     void DrawByBuff() ;//对绘图缓冲区中的数据进行绘图
408     BOOL SaveToFile(collect_t data) ;
409     void AddToDataList(collect_t data)  ;
410 
411 private:
412     void DrawBackGround() ;//绘制背景
413     void DrawCodinate() ;//绘制坐标
414 
415     void InsertDataToDrawBuff(collect_t) ;//将一个数据塞进缓冲区
416 
417     void InitDrawData(const DEAL_DATA *p_dealData) ;
418     void InitListData(HWND hWnd) ;
419     void InitSavePath(string path ) ;
420 private:
421     typedef struct
422     {
423         int m_validDataNum ;
424         int temp_x ;
425         int temp_y ;
426         POINT coodinateBuff[MAX_BUFF_NUM] ;
427     }DRAW_BUFF ;
428     typedef struct
429     {
430         RECT m_drawRect ;//绘图区矩形
431         HWND m_hDraw ;//绘图区句柄
432         int  m_timeGap ;
433         double m_aPiexValue ;//一个像素点对应电压值
434         double   m_aPiexTime ;//一个像素点对应毫秒数
435 
436         HDC    m_memDc ;
437         HDC    m_screenDc ;
438 
439         HBITMAP m_hBitMap ;
440         DRAW_BUFF m_drawBuff ;
441     }DRAW_DATA ;
442     typedef struct
443     {
444         HWND m_hDataList ;//数据列表句柄
445         int dataNum ;
446     }LIST_DATA ;
447     DRAW_DATA m_drawData ;
448     LIST_DATA m_listData ;
449     string m_savePath ;//数据保存文件路径    
450 } ;
451 
452 #endif
453 
454 /*datadealthread.cpp*/
455 #include "dealthread.h"
456 ////////////////////////////////////////////////////////////////////////////////
457 void DataDealThread::StartDeal( DEAL_DATA *p_dealData)
458 {
459 
460     collect_t dealBuff[USB_BUFF_SIZE] = {0x00} ;
461     size_t collectedNum =  0 ;
462     int i = 0 ;
463     //必要的数据初始化
464     DataInit( p_dealData ) ;
465     ADD_STRING_TO_EDIT(p_dealData->p_collectedData->hWorkState, "数据处理开始\n") ;
466 
467 
468     while(!p_dealData->p_collectedData->endDeal)
469     {        
470         InitializeCriticalSection( & p_dealData->p_collectedData->criticalSection ) ;
471     //    ADD_STRING_TO_EDIT(p_dealData->p_collectedData->hWorkState, "尝试进入关键段\n") ;
472         EnterCriticalSection( & p_dealData->p_collectedData->criticalSection ) ;
473 
474     //    ADD_STRING_TO_EDIT(p_dealData->p_collectedData->hWorkState, "进入关键段\n") ;
475             //可读则
476         if(p_dealData->p_collectedData->canBeReading)
477             {
478                 //拷贝数据到本地处理
479                 p_dealData->p_collectedData->canBeWriting = FALSE  ;
480                 collectedNum = p_dealData->p_collectedData->picCollectNum  ;
481                 memcpy(dealBuff, p_dealData->p_collectedData->data, collectedNum * 2 * sizeof(BYTE)) ;
482                 ADD_STRING_TO_EDIT(p_dealData->p_collectedData->hWorkState, "数据采集线程获取所采集数据\n") ;
483             p_dealData->p_collectedData->canBeReading = FALSE ;
484                 p_dealData->p_collectedData->canBeWriting = TRUE  ;
485         
486             //开始处理
487                 ADD_STRING_TO_EDIT(p_dealData->p_collectedData->hWorkState, "开始处理\n") ;
488             for(i = 0 ; i < collectedNum ; ++ i)
489                 {
490                 ADD_STRING_TO_EDIT(p_dealData->p_collectedData->hWorkState, "开正在处理0x%4x\n-- %f\n", dealBuff[i], TO_REAL_DATA(dealBuff[i])) ;
491 
492                     InsertDataToDrawBuff( dealBuff[i] ) ;
493                     DrawByBuff() ;        
494                     //数据加入显示列表
495                     AddToDataList( dealBuff[i] ) ;
496                 //保存到文件
497                     SaveToFile(dealBuff[i]) ;
498                 }
499             ADD_STRING_TO_EDIT(p_dealData->p_collectedData->hWorkState, "处理结束\n") ;
500 
501             }//如果可读     
502             //释放使用权
503         LeaveCriticalSection(& p_dealData->p_collectedData->criticalSection) ;
504         Sleep(300) ;
505         //检查是否有重绘通知
506         if(p_dealData->needRedraw)
507         {
508             //重绘
509             DrawByBuff() ;
510             //重绘完毕 
511             p_dealData->needRedraw = FALSE ;
512         }
513     }
514     
515 p_dealData->p_collectedData->endDeal = FALSE ;
516 ADD_STRING_TO_EDIT(p_dealData->p_collectedData->hWorkState, "数据处理结束\n") ;
517 
518 
519 }
520 ///////////////////////////////////////////////////////////////////
521 
522 
523 
524 
525 
526 void DataDealThread::InitListData(HWND hList)
527 {
528     m_listData.m_hDataList = hList ;
529     m_listData.dataNum = 0 ;
530 }
531 void DataDealThread::InitSavePath(string savePath)
532 {
533     m_savePath = savePath ;
534 }
535 
536 void DataDealThread::InitDrawData(const DEAL_DATA * p_dealData)
537 {
538     m_drawData.m_hDraw = p_dealData->h_drawCntl ;
539     GetClientRect(m_drawData.m_hDraw, &m_drawData.m_drawRect) ;
540 #if 0
541     m_drawData.m_drawRect.bottom -= 20 ;
542     m_drawData.m_drawRect.left   += 20 ;
543     m_drawData.m_drawRect.right  += 20 ;
544 #endif
545     m_drawData.m_timeGap = p_dealData->p_collectedData->picCollectTimeGap ;
546     m_drawData.m_aPiexTime =  m_drawData.m_timeGap / 10.0;//一个像素点代表几毫秒
547     m_drawData.m_aPiexValue = 0.03 ;//一个像素点代表几伏
548     m_drawData.m_screenDc = GetDC(m_drawData.m_hDraw) ;
549     m_drawData.m_memDc = CreateCompatibleDC(m_drawData.m_screenDc) ;
550     m_drawData.m_hBitMap = CreateCompatibleBitmap(m_drawData.m_screenDc, m_drawData.m_drawRect.right - m_drawData.m_drawRect.left,
551         m_drawData.m_drawRect.bottom - m_drawData.m_drawRect.top) ;
552     SelectObject(m_drawData.m_memDc, m_drawData.m_hBitMap ) ;
553     memset(m_drawData.m_drawBuff.coodinateBuff, 0x00, USB_BUFF_SIZE*sizeof(POINT)) ;
554     m_drawData.m_drawBuff.m_validDataNum = 0 ;
555     m_drawData.m_drawBuff.temp_x =  m_drawData.m_drawRect.left;
556     m_drawData.m_drawBuff.temp_y = 0 ;
557 }
558 void DataDealThread::DataInit(const DEAL_DATA * p_dealData)
559 {
560     InitDrawData(p_dealData) ;
561     InitListData(p_dealData->h_listCntl) ;
562      InitSavePath(p_dealData->savePath) ;
563 }
564 void DataDealThread::DrawInit()
565 {
566     //绘制背景
567     DrawBackGround() ;
568     //绘制坐标
569     DrawCodinate() ;
570 }
571 //绘制背景
572 void DataDealThread::DrawBackGround()
573 {
574     HBRUSH brush = CreateSolidBrush(RGB(0,0,0)) ;
575     FillRect(m_drawData.m_memDc, &m_drawData.m_drawRect, brush) ;
576 }
577 //绘制坐标线
578 void DataDealThread::DrawCodinate()
579 {
580     HPEN hPen ;
581     /******************绘制y朝向坐标线******************/
582     hPen = CreatePen(PS_SOLID, 1,RGB(0,50,0) ) ;
583     SelectObject(m_drawData.m_memDc,hPen) ;
584     for(int x = m_drawData.m_drawRect.left ; x < m_drawData.m_drawRect.right ; x += m_drawData.m_timeGap / m_drawData.m_aPiexTime)
585     {
586         MoveToEx(m_drawData.m_memDc,x,  m_drawData.m_drawRect.bottom,NULL) ;
587         
588         LineTo(m_drawData.m_memDc, x,0);
589     }
590     DeleteObject(hPen) ;
591 
592     /*******************绘制x朝向坐标线**************************/
593     hPen = CreatePen(PS_SOLID, 1,RGB(0,50,0) ) ;
594     SelectObject(m_drawData.m_memDc,hPen) ;
595     //绘制正向
596     for(int y = m_drawData.m_drawRect.bottom / 2 ; y > m_drawData.m_drawRect.top ; y -= 10 ) //(double)1 / m_drawData.m_aPiexValue)
597     {
598         MoveToEx(m_drawData.m_memDc,m_drawData.m_drawRect.left,  y,NULL) ;
599         //TextOut(
600         LineTo(m_drawData.m_memDc, m_drawData.m_drawRect.right ,y);
601     }
602     //绘制负向
603     for( y = m_drawData.m_drawRect.bottom / 2 ; y < m_drawData.m_drawRect.bottom ; y += 10 )//(double)1 / m_drawData.m_aPiexValue)
604     {
605         MoveToEx(m_drawData.m_memDc,m_drawData.m_drawRect.left,  y,NULL) ;
606         LineTo(m_drawData.m_memDc, m_drawData.m_drawRect.right ,y);
607 }
608     DeleteObject(hPen) ;
609 }
610 /*
611 *将两字节数据送入绘图坐标缓冲,将每次送入的数据转换为合理的坐标
612 */
613 void DataDealThread::InsertDataToDrawBuff(WORD data)
614 {
615     int i = 0 ;
616     static int inc_x = m_drawData.m_timeGap / m_drawData.m_aPiexTime ;
617     static int middle_y = m_drawData.m_drawRect.bottom ;
618     m_drawData.m_drawBuff.temp_y = middle_y - ( TO_REAL_DATA(data) / m_drawData.m_aPiexValue) ;
619 
620     if(m_drawData.m_drawBuff.temp_x >= m_drawData.m_drawRect.right )
621     {
622         m_drawData.m_drawBuff.temp_x -= inc_x ;
623         //左移坐标缓冲
624         memmove(m_drawData.m_drawBuff.coodinateBuff, m_drawData.m_drawBuff.coodinateBuff+1, sizeof(POINT) * ( m_drawData.m_drawBuff.m_validDataNum - 1)) ;
625         --m_drawData.m_drawBuff.m_validDataNum ;
626 
627         for(i = 0; i< m_drawData.m_drawBuff.m_validDataNum ; ++ i)
628         {
629             m_drawData.m_drawBuff.coodinateBuff[i].x -= inc_x ;
630         }
631     }
632     m_drawData.m_drawBuff.coodinateBuff[m_drawData.m_drawBuff.m_validDataNum].x =  m_drawData.m_drawBuff.temp_x;
633     m_drawData.m_drawBuff.coodinateBuff[m_drawData.m_drawBuff.m_validDataNum].y =  m_drawData.m_drawBuff.temp_y;
634     ++m_drawData.m_drawBuff.m_validDataNum ;
635     m_drawData.m_drawBuff.temp_x += inc_x ;
636     
637 }
638 /*
639 根据坐标缓冲进行波形绘制
640 */
641 void DataDealThread::DrawByBuff()
642 {
643 int i ;
644 HPEN hPen ;
645 
646     this->DrawBackGround() ;
647     this->DrawCodinate() ;
648     for(i = 0; i < m_drawData.m_drawBuff.m_validDataNum; ++ i )
649     {
650         hPen = CreatePen(PS_SOLID, 1,RGB(255,0,0) ) ;
651         SelectObject(m_drawData.m_memDc,hPen) ;
652         if(i == 0)
653         {
654             MoveToEx(m_drawData.m_memDc, m_drawData.m_drawBuff.coodinateBuff[i].x,m_drawData.m_drawBuff.coodinateBuff[i].y
655         ,NULL) ;
656             continue ;
657         }
658 
659         LineTo(m_drawData.m_memDc, m_drawData.m_drawBuff.coodinateBuff[i].x,m_drawData.m_drawBuff.coodinateBuff[i].y ) ;
660     
661 
662         DeleteObject(hPen) ;
663 
664     }
665 
666 #if 1
667 
668 BitBlt(m_drawData.m_screenDc, m_drawData.m_drawRect.left,  m_drawData.m_drawRect.top,
669      m_drawData.m_drawRect.right - m_drawData.m_drawRect.left,
670     m_drawData.m_drawRect.bottom - m_drawData.m_drawRect.top,
671 
672     m_drawData.m_memDc, m_drawData.m_drawRect.left,  m_drawData.m_drawRect.top,SRCCOPY )  ;
673 #endif
674 }
675 
676 void DataDealThread::AddToDataList(WORD data)
677 {
678     //static unsigned long index = 0 ;
679     char buff[50] = "" ;
680     static LVITEM lvItem ;
681     memset(&lvItem, 0x00, sizeof(LVITEM) ) ;
682     //data = 0x294 ;
683     float x = TO_REAL_DATA(data) ;
684     lvItem.mask = LVIF_TEXT ;
685     lvItem.iItem =  ++m_listData.dataNum ;
686     lvItem.cchTextMax = MAX_PATH ;
687     lvItem.iSubItem = 0;//m_listData.dataNum ;
688     sprintf(buff, "%f V",TO_REAL_DATA(data)) ;
689     lvItem.pszText = buff ;
690     SendMessage(m_listData.m_hDataList, LVM_INSERTITEM, 0, (LPARAM)&lvItem) ;    
691 
692 }
693 BOOL DataDealThread::SaveToFile(collect_t data)
694 {
695     FILE *saveStream = fopen(m_savePath.c_str(), "at+") ;
696     if(saveStream == NULL)
697         return FALSE;
698     fprintf(saveStream,"%f\n",TO_REAL_DATA(data));
699     fclose(saveStream);
700     return TRUE ;
701 }
上位机主控程序制模块代码
703 #include <windows.h>
704 #include "resource.h"
705 #include "maindlg.h"
706 
707 
708 MainDlg mainDlg;//主程序对话框
709 BOOL CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM) ;//主对话框消息处理
710 int APIENTRY WinMain(HINSTANCE hInstance,
711                      HINSTANCE hPrevInstance,
712                      LPSTR     lpCmdLine,
713                      int       nCmdShow)
714 {
715     LoadLibrary(TEXT("RICHED32.DLL") ) ;
716     InitCommonControls() ;
717     LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));
718     DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG_DATA_GET), NULL, DlgProc) ;
719 
720     return 0;
721 }
722 
723 
724 BOOL CALLBACK DlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
725 {
726 
727     static int times = 1;
728 #if 0
729     
730     HDC hdc ;
731     PAINTSTRUCT ps ;
732     RECT rect ;
733 
734 #endif
735 
736     
737 
738     switch(message)
739     {
740     
741     case WM_COMMAND:
742         switch(LOWORD(wParam))
743         {
744         case IDC_BUTTON_BEGIN_CONNECT:
745             if( mainDlg.BeginConnect() )//开始连接
746             {//连接成功
747                 mainDlg.EnableAChildCntl(IDC_BUTTON_BEGIN_CONNECT,  FALSE) ;
748                 mainDlg.PrintConnectState() ;//显示连接状态
749                 mainDlg.EnableAChildCntl(IDC_BUTTON_BEGIN_COLLECT, TRUE) ; //开始采集开关可用
750             }
751             else
752             {//连接失败
753                 mainDlg.PrintErr(TEXT("连接失败")) ;
754             }
755             break;
756         case IDC_BUTTON_BEGIN_COLLECT://开始采集
757             if(!mainDlg.IsConnected())
758             {//如果未连接上
759                 mainDlg.PrintErr(TEXT("未连接上下位机,无法进行采集")) ;
760             }
761             else
762             {//已连接上
763                 mainDlg.GetDataFromDialog() ;//从对话框读取数据
764                 if(mainDlg.CheckParameter())
765                 {//正确参数检查
766             
767                     if(mainDlg.IsAutoCollect())
768                     {//自动采集
769                         mainDlg.EnableAChildCntl(IDC_BUTTON_BEGIN_COLLECT,  FALSE) ;
770                         mainDlg.EnableAChildCntl(IDC_BUTTON_STOP_COLLECT,  TRUE) ;
771                     }
772                     else if(mainDlg.IsHandCollect())
773                     {//手动采集
774                         mainDlg.EnableAChildCntl(IDC_BUTTON_BEGIN_COLLECT,  FALSE) ;
775                         mainDlg.EnableAChildCntl(IDC_BUTTON_STOP_COLLECT,  FALSE) ;
776                     }
777                     else
778                     {//采集方式未设定
779                         mainDlg.PrintErr(TEXT("未设定采集方式")) ;
780                     }
781 
782                     if(times ++ == 1)
783                     {
784                         mainDlg.BeginDataDealThread() ;//启动数据处理线程
785                     }
786 
787                     mainDlg.BeginCollectThread() ;//开始采集线程
788                 
789                 }
790             }
791             break;
792 
793         case IDC_BUTTON_STOP_COLLECT://停止采集
794             if(mainDlg.IsCollecting())
795             {//正在采集 
796             //结束采集线程
797                 mainDlg.EndCollectThread() ;
798             //    mainDlg.EndDataDealThread() ;
799                 mainDlg.EnableAChildCntl(IDC_BUTTON_BEGIN_COLLECT,  TRUE) ;
800             //    mainDlg.EnableAChildCntl(IDC_BUTTON_STOP_COLLECT,  FALSE) ;
801             }
802             break;
803             
804 
805         case IDC_BUTTON_GET_SAVEPATH:
806             

807                 mainDlg.GetSaveFileName() ;
808             
809             break ;
810         case IDC_RADIO_HAND_COLLECT:
811             mainDlg.SetCollectMode_HAND() ;
812             break;
813         case IDC_RADIO_AUTO_COLLECT:
814             mainDlg.SetCollectMode_AUTO() ;
815             break ;
816         case IDCANCEL:
817             mainDlg.EndDataDealThread() ;
818             Sleep(300) ;
819             EndDialog(hWnd, 0) ;
820             break ;
821         
822         }
823         return 0 ;
824     case WM_END_COLLECT://采集线程结束
825         mainDlg.EnableAChildCntl(IDC_BUTTON_BEGIN_COLLECT,  TRUE) ;
826         mainDlg.EnableAChildCntl(IDC_BUTTON_STOP_COLLECT,  FALSE) ;
827             return 0 ;
828     case WM_PAINT:
829         mainDlg.SendPaintMessageToDealThread() ;
830         return 0 ;
831 
832     case WM_INITDIALOG:
833         mainDlg.InitDlgHwnd(hWnd) ;
834         mainDlg.PrintConnectState() ;
835         mainDlg.DoSomeCntlInt() ;
836         mainDlg.DoSomeDataInit() ;
837         mainDlg.EnableAChildCntl(IDC_BUTTON_BEGIN_COLLECT, FALSE) ;
838         mainDlg.EnableAChildCntl(IDC_BUTTON_STOP_COLLECT, FALSE) ;
839         return 0 ;
840     
841     }
842 
843     return 0 ;
844 
845 }

 

分类:

技术点:

相关文章:

  • 2021-12-16
  • 2021-12-04
  • 2021-11-24
  • 2021-04-05
  • 2021-05-20
  • 2021-06-27
  • 2021-06-26
  • 2021-08-04
猜你喜欢
  • 2022-12-23
  • 2021-12-18
  • 2022-12-23
  • 2021-05-06
  • 2021-08-12
  • 2022-12-23
  • 2021-05-12
相关资源
相似解决方案