基于PIC的数据采集系统---上位机设计

基于PIC的数据采集系统---上位机设计

2023年6月22日发(作者:)

基于PIC的数据采集系统---上位机设计基本功能  在本设计中,数据的处理可以使⽤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 5 #include 6 #include 7 #include "commonuse.h" 8 using std::string; 9 #pragma comment( lib, "" ) 10 extern "C" { 11 #include "hidsdi.h" 12 } 13 #pragma comment( 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 /*源⽂件*/ 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 else101 {102

103 ErrorStatus = GetLastError();104 SetupDiDestroyDeviceInfoList(DeviceInfoTable);

105 return FALSE;

106 }107

108 = 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_H208 #define COLLECT_THREAD_H209

210 #include "commonuse.h"211 #include "hid.h"212 #include 213 #include 214 class DataCollectThread215 {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 #endif243 /**/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 else280 {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 wantNum309

310 } ;311 BYTE stateBuff[USB_BUFF_SIZE] = {0} ;312

313 #if 1314

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 #endif327

328 329 #if 0330 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 #endif342

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_THREAD362 #define DRAW_THREAD363

364 #include "commonuse.h"365 #include "draw.h"366 #include 367 #include 368 #include 369 #include 370 #include 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 struct422 {423 int m_validDataNum ;424 int temp_x ;425 int temp_y ;426 POINT coodinateBuff[MAX_BUFF_NUM] ;427 }DRAW_BUFF ;428 typedef struct429 {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 struct443 {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 #endif453

454 /**/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%4xn-- %fn", 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_m = 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 0541 m_drawData.m_ -= 20 ;542 m_drawData.m_ += 20 ;543 m_drawData.m_ += 20 ;544 #endif545 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_ - m_drawData.m_,551 m_drawData.m_ - m_drawData.m_) ;552 SelectObject(m_drawData.m_memDc, m_drawData.m_hBitMap ) ;553 memset(m_drawData.m_ateBuff, 0x00, USB_BUFF_SIZE*sizeof(POINT)) ;554 m_drawData.m_drawBuff.m_validDataNum = 0 ;555 m_drawData.m__x = m_drawData.m_;556 m_drawData.m__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_ ; x < m_drawData.m_ ; x += m_drawData.m_timeGap / m_drawData.m_aPiexTime)585 {586 MoveToEx(m_drawData.m_memDc,x, m_drawData.m_,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_ / 2 ; y > m_drawData.m_ ; y -= 10 ) //(double)1 / m_drawData.m_aPiexValue)597 {598 MoveToEx(m_drawData.m_memDc,m_drawData.m_, y,NULL) ;599 //TextOut(600 LineTo(m_drawData.m_memDc, m_drawData.m_ ,y);601 }602 //绘制负向603 for( y = m_drawData.m_ / 2 ; y < m_drawData.m_ ; y += 10 )//(double)1 / m_drawData.m_aPiexValue)604 {605 MoveToEx(m_drawData.m_memDc,m_drawData.m_, y,NULL) ;606 LineTo(m_drawData.m_memDc, m_drawData.m_ ,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_ ;618 m_drawData.m__y = middle_y - ( TO_REAL_DATA(data) / m_drawData.m_aPiexValue) ;619

620 if(m_drawData.m__x >= m_drawData.m_ )621 {622 m_drawData.m__x -= inc_x ;623 //左移坐标缓冲624 memmove(m_drawData.m_ateBuff, m_drawData.m_ateBuff+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_ateBuff[i].x -= inc_x ;630 }631 }632 m_drawData.m_ateBuff[m_drawData.m_drawBuff.m_validDataNum].x = m_drawData.m__x;633 m_drawData.m_ateBuff[m_drawData.m_drawBuff.m_validDataNum].y = m_drawData.m__y;634 ++m_drawData.m_drawBuff.m_validDataNum ;635 m_drawData.m__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_ateBuff[i].x,m_drawData.m_ateBuff[i].y655 ,NULL) ;656 continue ;657 }658

659 LineTo(m_drawData.m_memDc, m_drawData.m_ateBuff[i].x,m_drawData.m_ateBuff[i].y ) ;660

661

662 DeleteObject(hPen) ;663

664 }665

666 #if 1667

668 BitBlt(m_drawData.m_screenDc, m_drawData.m_, m_drawData.m_,669 m_drawData.m_ - m_drawData.m_,670 m_drawData.m_ - m_drawData.m_,671

672 m_drawData.m_memDc, m_drawData.m_, m_drawData.m_,SRCCOPY ) ;673 #endif674 }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 = LVIF_TEXT ;685 = ++m_m ;686 tMax = MAX_PATH ;687 em = 0;//m_m ;688 sprintf(buff, "%f V",TO_REAL_DATA(data)) ;689 t = 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,"%fn",TO_REAL_DATA(data));699 fclose(saveStream);700 return TRUE ;701 }上位机主控程序制模块代码703 #include 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("") ) ;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 0729

730 HDC hdc ;731 PAINTSTRUCT ps ;732 RECT rect ;733

734 #endif735

736

737

738 switch(message)739 {740

741 case WM_COMMAND:742 switch(LOWORD(wParam))743 {744 case IDC_BUTTON_BEGIN_CONNECT:745 if( onnect() )//开始连接746 {//连接成功747 AChildCntl(IDC_BUTTON_BEGIN_CONNECT, FALSE) ;748 onnectState() ;//显⽰连接状态749 AChildCntl(IDC_BUTTON_BEGIN_COLLECT, TRUE) ; //开始采集开关可⽤750 }751 else752 {//连接失败753 rr(TEXT("连接失败")) ;754 }755 break;756 case IDC_BUTTON_BEGIN_COLLECT://开始采集757 if(!ected())758 {//如果未连接上759 rr(TEXT("未连接上下位机,⽆法进⾏采集")) ;760 }761 else762 {//已连接上763 aFromDialog() ;//从对话框读取数据764 if(arameter())765 {//正确参数检查766

767 if(Collect())768 {//⾃动采集769 AChildCntl(IDC_BUTTON_BEGIN_COLLECT, FALSE) ;770 AChildCntl(IDC_BUTTON_STOP_COLLECT, TRUE) ;771 }772 else if(Collect())773 {//⼿动采集774 AChildCntl(IDC_BUTTON_BEGIN_COLLECT, FALSE) ;775 AChildCntl(IDC_BUTTON_STOP_COLLECT, FALSE) ;776 }777 else778 {//采集⽅式未设定779 rr(TEXT("未设定采集⽅式")) ;780 }781

782 if(times ++ == 1)783 {784 ataDealThread() ;//启动数据处理线程785 }786

787 ollectThread() ;//开始采集线程788

789 }790 }791 break;792

793 case IDC_BUTTON_STOP_COLLECT://停⽌采集794 if(ecting())795 {//正在采集

796 //结束采集线程797 lectThread() ;798 // aDealThread() ;799 AChildCntl(IDC_BUTTON_BEGIN_COLLECT, TRUE) ;800 // AChildCntl(IDC_BUTTON_STOP_COLLECT, FALSE) ;801 }802 break;803

804

805 case IDC_BUTTON_GET_SAVEPATH:806

807 eFileName() ;808

809 break ;810 case IDC_RADIO_HAND_COLLECT:811 lectMode_HAND() ;812 break;813 case IDC_RADIO_AUTO_COLLECT:814 lectMode_AUTO() ;815 break ;816 case IDCANCEL:817 aDealThread() ;818 Sleep(300) ;819 EndDialog(hWnd, 0) ;820 break ;821

822 }823 return 0 ;824 case WM_END_COLLECT://采集线程结束825 AChildCntl(IDC_BUTTON_BEGIN_COLLECT, TRUE) ;826 AChildCntl(IDC_BUTTON_STOP_COLLECT, FALSE) ;827 return 0 ;828 case WM_PAINT:829 intMessageToDealThread() ;830 return 0 ;831

832 case WM_INITDIALOG:833 gHwnd(hWnd) ;834 onnectState() ;835 CntlInt() ;836 DataInit() ;837 AChildCntl(IDC_BUTTON_BEGIN_COLLECT, FALSE) ;838 AChildCntl(IDC_BUTTON_STOP_COLLECT, FALSE) ;839 return 0 ;840

841 }842

843 return 0 ;844

845 }

发布者:admin,转转请注明出处:http://www.yc00.com/news/1687430105a9414.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信