freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

基于rs232接口的數(shù)據(jù)采集分析系統(tǒng)研究于碩(編輯修改稿)

2025-07-24 18:42 本頁面
 

【文章內(nèi)容簡介】 //設(shè)置波特率連接以及斷開連接、詢問是否連接: bool Connect()。 void Disconnect()。 bool isConnected()。發(fā)送、收取一條信息: bool SendSigmaMsg(const char* msg)。 //發(fā)送一條指令、信息 bool GetSigmaMsg(char* msg)。有關(guān)參數(shù)的設(shè)置以及查詢: void SetApertureAera(float area)。 bool GetApertureAera(floatamp。 ans)。 void SetAreaCorrection( BOOL setValue )。 bool GetAreaCorrection(BOOLamp。 ans)。立即執(zhí)行一次測量并讀取測量值,成功返回true,并將結(jié)果存儲在ans中,否則返回false: bool GetDataImmediate(doubleamp。 ans)。查詢相關(guān)的器件信息: bool GetDeviceSn( char* sigma_sn )。 bool GetProbeSn( char* probe_sn )。 bool GetProbeModel( char* probe_model )。子線程函數(shù):CommProc這個函數(shù)主要負(fù)責(zé)通信,并將結(jié)果存儲在緩沖區(qū)當(dāng)中,當(dāng)收到終止符(回車換行)的時候,選擇是否發(fā)送消息。函數(shù)結(jié)構(gòu)如圖:開始執(zhí)行是否設(shè)置了父窗口報錯并退出是否仍在連接狀態(tài)中檢查串口緩沖區(qū)是否有數(shù)據(jù)讀取數(shù)據(jù),并根據(jù)是否是終止符選擇是否發(fā)送消息進(jìn)入事件等待,直到收到串口的Event斷開連接并退出否否否是是是 程序CommProc線程結(jié)構(gòu)圖CommProc是通信線程函數(shù),負(fù)責(zé)整個程序與終端機(jī)的通信,同時將接收到的數(shù)據(jù)以原來的格式存儲到緩沖區(qū)。下面詳細(xì)介紹CommProc。 調(diào)用時機(jī)當(dāng)用戶點擊連接按鈕之后,程序執(zhí)行TSigma::Connect()函數(shù),Connect函數(shù)將串口按照指定參數(shù)設(shè)置好之后,使用AfxBeginThread()將該線程打開并掛起,然后Connect函數(shù)檢查AfxBeginThread()函數(shù)返回的指針,確認(rèn)非空后(說明打開線程正常),開始執(zhí)行。 函數(shù)參數(shù)由于線程函數(shù)是傳遞給windows指針,由windows調(diào)用的,所以函數(shù)必須符合規(guī)定的格式,函數(shù)的參數(shù)只能有一個32位的pParam,當(dāng)然這個參數(shù)是什么內(nèi)容,由用戶來定,但是必須是LPVOID類型(可以強制轉(zhuǎn)換為任何類型的指針)。很明顯,當(dāng)我們有大量參數(shù)需要傳遞的時候,指針作為參數(shù)最為合適。雖然CommProc是TSigma的成員函數(shù),但因為這個函數(shù)的特殊性,它必須是一個Static型,否則無法由系統(tǒng)調(diào)用。Static型函數(shù)是不能直接調(diào)用它的類成員(因為它不知道是應(yīng)該是哪一個類,或者說類沒有實例化,static函數(shù)是沒有this指針的),所以我們需要將實例化的類指針傳遞給函數(shù),其實就是普通成員函數(shù)的this指針。 返回值根據(jù)stdcall函數(shù)的規(guī)定,函數(shù)調(diào)用正常,返回0,否則返回非0值,表示錯誤代碼。 執(zhí)行過程進(jìn)入函數(shù)之后,首先檢查是否有父窗口(僅在調(diào)試時有該過程)。完成函數(shù)變量的初始化之后就進(jìn)入線程的循環(huán),循環(huán)條件為:仍在連接狀態(tài)中,即m_bConnected的值為true。循環(huán)過程很簡單,檢查串口緩沖區(qū),有數(shù)據(jù)則讀取,并放入自己的緩沖區(qū),然后檢查是否是終止符,考慮要不要發(fā)送消息。然后就用WaitForSigleEvent等待串口事件。Get*函數(shù)這些函數(shù)有 bool GetApertureAera(floatamp。 ans)。 bool GetAreaCorrection(BOOLamp。 ans)。 bool GetDataImmediate(doubleamp。 ans)。 bool GetDeviceSn( char* sigma_sn )。 bool GetProbeSn( char* probe_sn )。 bool GetProbeModel( char* probe_model )。這些函數(shù)都大同小異:關(guān)閉CommProc的消息發(fā)送功能(將m_fSendMessages設(shè)置為0,由函數(shù)自己來處理消息),然后給終端機(jī)發(fā)送請求數(shù)據(jù)的指令,并等待接收到終止符,等待用WaitForSigleEvent函數(shù)進(jìn)行,設(shè)置最長等待時間為500ms來防止阻塞進(jìn)程。例如bool TSigma::GetDeviceSn( char* sigma_sn ){ m_fSendMessage=false。 ResetEvent(m_hReceived)。 SendSigmaMsg(SYST:INFO:INST:SERN?)。 WaitForSingleObject(m_hReceived,m_nResponseTime)。 m_fSendMessage=true。 if( GetSigmaMsg(sigma_sn) ) return true。 return false。}函數(shù)的返回值都是布爾型,true表示執(zhí)行成功,false表示執(zhí)行失敗,而實際的數(shù)據(jù)存儲在傳遞給函數(shù)的指針指向的空間中。串口連接的關(guān)閉關(guān)閉串口連接是通過標(biāo)志位來實現(xiàn)的,這個地方萬萬不可以使用KillThread函數(shù)來終止線程,要否定線程內(nèi)自己的循環(huán)條件來終止,并且要等待線程內(nèi)循環(huán)的結(jié)束,否則會引起內(nèi)存泄露:void TSigma::Disconnect(){ if(m_bConnected==false) return。 m_bConnected=false。 SetCommMask(m_hPort,0)。 WaitForSingleObject(m_pThreadm_hThread,INFINITE)。 m_pThread=NULL。 CloseHandle(m_hPort)。} 程序主要功能的設(shè)計概述程序要完成數(shù)據(jù)的采集和動態(tài)顯示,并且能將采集的數(shù)據(jù)存儲起來。為了快速的實現(xiàn)這些功能,我們使用MFC內(nèi)建的DocumentView結(jié)構(gòu),并使用其內(nèi)建的Serialize機(jī)制實現(xiàn)存儲功能,這樣可以方便的讓我們的程序打開自己的文件,并且就如同數(shù)據(jù)采集時那樣顯示數(shù)據(jù)圖像。程序中,采集的數(shù)據(jù)使用數(shù)組的方式存儲,這樣明確了各個數(shù)據(jù)的時間關(guān)系,并且能夠快速的遍歷、檢索出所需要的數(shù)據(jù),實現(xiàn)高級的計算要求,為以后程序功能的擴(kuò)展提供了方便。因為我們對數(shù)據(jù)采集的速率要求并不高,一般在10Hz左右,所以沒有使用復(fù)雜的方法進(jìn)行定時,自動采集,而是簡單的設(shè)置一個以采樣周期為基準(zhǔn)的定時器,定時執(zhí)行GetDataImmediate成員函數(shù),并在每次采集回數(shù)據(jù)之后刷新顯示。最終我們的程序界面設(shè)計如下圖 程序界面我們使用了Visual Studio 2010提供的最新的Ribbon界面,使用時,先在左側(cè)的Connect選項卡設(shè)置好端口號和波特率,然后進(jìn)行連接,連接成功后,程序會在下方的狀態(tài)區(qū)顯示連接成功,并顯示出功率計的序列號。連接完成后,就可以設(shè)置采樣周期,按下START按鈕開始采集。一旦開始采集后,采樣周期設(shè)置框自動鎖死,不能再更改。采集完成后,按下STOP按鈕終止采集。采集過程中,在右上方的CurrentValue框中可以看到當(dāng)前功率,選中Hold復(fù)選框后,當(dāng)前功率數(shù)值將鎖定,取消Hold之后恢復(fù)顯示當(dāng)前功率。采集完成后,可以使用程序的存儲功能將數(shù)據(jù)存儲起來。在程序執(zhí)行的任意時刻,可以使用自帶的截圖功能,將數(shù)據(jù)圖像復(fù)制到剪貼板。數(shù)據(jù)存儲結(jié)構(gòu)的設(shè)計因為存儲的內(nèi)容很簡單,單純的浮點數(shù),所以使用線性數(shù)組來存儲,MFC提供CArray最合適不過,而且還支持Serialize功能,省去了文件存儲的許多麻煩。除了從終端讀取的數(shù)據(jù)需要存儲之外,我們還需要將讀取的周期存儲起來。數(shù)據(jù)和周期是必須的,另外為了加速程序的執(zhí)行,我們將最大值一并存儲了起來,因為最大值是一個頻繁使用的值,尤其是在繪圖的過程中。下面是3SigmaDoc的成員變量:public: CArraydouble,double m_dataArray。 double max_ans。 int m_peroid。存儲、讀取函數(shù)void CMy3SigmaDoc::Serialize(CArchiveamp。 ar){ if (()){ armax_ans。 arm_peroid。 (ar)。 } else{ armax_ans。 arm_peroid。 (ar)。 }}數(shù)據(jù)的繪圖顯示在繪制的過程中,我們將當(dāng)前屏幕的位置計算出來,只繪制當(dāng)前屏幕顯示的內(nèi)容,而不是繪制所有畫幅來提高繪圖效率。繪圖的過程可以分為四步: 根據(jù)數(shù)據(jù)量,單位間隔計算畫幅大小,并設(shè)置畫幅大小。 GetClientRect(amp。ClientRect)。 =()。 =()。 int t_max=(()START_X)/(axis_x_interval)。 if(nSize*periodt_max*1000){ t_max=nSize*period/1000+1。 =(period*nSize*axis_x_interval/1000)+START_X+START_X。 =()。 SetScrollSizes(MM_TEXT,sizeTotal)。 }else{ SetScrollSizes(MM_TEXT,sizeTotal)。 } 繪制橫向表格,并添加橫坐標(biāo)(以秒為單位) t_max=GetScrollPos(SB_HORZ)/axis_x_interval+(()START_X)/(axis_x_interval)+1。 for(int t=GetScrollPos(SB_HORZ)/axis_x_interval。t=t_max。t++) { int i=t*axis_x_interval+START_X。 pDCMoveTo(i,0)。 pDCLineTo(i,())。 sprintf_s(text,100,%ds,t)。 (i,()START_Y+5,i+50,())。 pDCDrawText(text,amp。textRect,DT_LEFT)。 } pDCSelectObject(pOldPen)。 ()。 根據(jù)最大值繪制縱向表格,并添加縱坐標(biāo) (PS_SOLID,1,RGB(200,200,200))。 pOldPen=pDCSelectObject(amp。pen)。 for(int i=0。i=axis_y_num。i++) { pDCMoveTo(START_X,()START_Yaxis_y_grid*i)。 pDCLineTo(,()START_Yaxis_y_grid*i)。 (0,()START_Yaxis_y_grid*i, START_X,()START_Yaxis_y_grid*i+50)。 sprintf_s(text,sizeof(text),%,i*axis_y_interval)。 pDCDrawText(text,amp。textRect,DT_RIGHT)。 } pDCSelectObject(pOldPen)。 ()。 繪制曲線 (PS_SOLID,2,RGB(0,255,255))。 pOldPen = pDCSelectObject(amp。pen)。 pDCMoveTo(START_X,()START_Y)。 int imin=1000*GetScrollPos(SB_HORZ)/(period*axis_x_interval)。 int imax=min(imin+1000*()/(period*axis_x_interval)+1,pDoc())。 for(int i=imin。iimax。i++) { int x=(int)(START_X+period*i*axis_x_interval/1000)。 int y=(int)(()(START_Y+axis_y_grid/axis_y_interval*pDocm_dataArray[i]))。 pDCLineTo(x,y)。 }Ribbon控件的使用 RibbonRibbon是Visual Studio 2010最新提供的界面方案,實際上我們在用Office2007的時候就看到過了。Ribbon界面很漂亮,不是C++原生的,但絲毫不影響我們的使用及它的便利性,唯一略顯麻煩的是控件類獲取,但Ribbon控件的類可以直接用控件ID來獲取,實際上非常方便的,我們不必再費心思考慮控件變量的存儲位置、作用范圍,只需要在使用的時候獲取控件就好了。例如上圖中BaudRate的消息處理函數(shù):void CMy3SigmaView::OnComboBaud(){ CMainFrame *pFrame =(CMainFrame*)(AfxGetApp()m_pMainWnd)。 CMFCRibbonComboBox *ctrl_baud=DYNAMIC_DOWNCAST( CMFCRibbonComboBox,pFrame(ID_COMBO_BAUD))。 int nindex=ctrl_baudGetCurSel()。 (atoi(ctrl_baudGetItem(nindex)))。}數(shù)據(jù)采集的開始與終止當(dāng)我們設(shè)置好串口相關(guān)的參數(shù),連接好,并設(shè)置好采樣周期之后,就可以開始數(shù)據(jù)采集。采集數(shù)據(jù)時,因為采樣周期不會很高,所以采
點擊復(fù)制文檔內(nèi)容
范文總結(jié)相關(guān)推薦
文庫吧 www.dybbs8.com
備案圖片鄂ICP備17016276號-1