📄 simulationview.cpp
字号:
// SimulationView.cpp : implementation of the CSimulationView class
//
#include "stdafx.h"
#include "Simulation.h"
#include "SimulationDoc.h"
#include "SimulationView.h"
#include "Afxmt.h"
#include "GroupDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CSimulationView
//定义用于终止数据采集、启动动态显示和终止动态显示的线程同步信号
CEvent threadReadEnd;
CEvent threadShowStart;
CEvent threadShowEnd;
/*----------------------------------------------------------------------------
function: 数据采集线程函数
parameters:
param 指向视窗的指针
author: 唐富华
date: 2004.5.14
-----------------------------------------------------------------------------*/
UINT ThreadRead(LPVOID param)
{
char state;
unsigned short data;
int mydata;
BOOL KeepRunning = true;
//根据传进来的视窗指针参数获取指向文档的指针
CSimulationDoc* pDoc = (CSimulationDoc*)((CSimulationView*)param)->GetDocument();
while(KeepRunning)
{
_asm//检测FIFO是否为非空
{
mov dx,1000h
in al,dx
mov state,al
}
state=state&1;
if(state)//若FIFO非空,则从数据口地址读取长度为一个字的数据
{
_asm
{
mov dx,1002h
in ax,dx
mov data,ax
}
mydata=data>>2;//读取的原始数据的最后一位为标志位:为0时为剪力数据;为1时为重力数据
if(data%2==0)
{
pDoc->m_ReadSRBuffer[pDoc->m_ReadSRLen++]=mydata;
}
else
pDoc->m_ReadWTBuffer[pDoc->m_ReadWTLen++]=mydata;
//如果读满一帧数据则将其保存到文件,同时显示其波形
if(pDoc->m_ReadSRLen>=BUFFERREAD_LEN||pDoc->m_ReadWTLen>=BUFFERREAD_LEN)
{
//保存数据到文件
((CSimulationView*)param)->SaveDataToFile(pDoc->m_ReadSRBuffer,pDoc->m_ReadSRLen,pDoc->m_ReadWTBuffer,pDoc->m_ReadWTLen);
//按一定的间隔从采集数据缓冲区提取数据到显示缓冲区
pDoc->GetShowDataFromBuffer();
//启动波形显示线程
threadShowStart.SetEvent();
//重置读取数据长度标志并清空数据采集缓冲区
memset(pDoc->m_ReadSRBuffer,0,BUFFERREAD_LEN*sizeof(unsigned short));
memset(pDoc->m_ReadWTBuffer,0,BUFFERREAD_LEN*sizeof(unsigned short));
pDoc->m_ReadSRLen=0;
pDoc->m_ReadWTLen=0;
//挂起20毫秒让波形显示线程获得执行
Sleep(20);
}
}
//等待数据采集终止信号,若有信号则终止循环
int result=::WaitForSingleObject(threadReadEnd.m_hObject,0);
if(result==WAIT_OBJECT_0)
KeepRunning =false;
}
//保存最后采集到的数据
((CSimulationView*)param)->SaveDataToFile(pDoc->m_ReadSRBuffer,pDoc->m_ReadSRLen,pDoc->m_ReadWTBuffer,pDoc->m_ReadWTLen);
//在线程终止前关闭重力和剪力数据文件指针
((CSimulationView*)param)->SRFile.Close();
((CSimulationView*)param)->WTFile.Close();
//按一定的间隔从采集的最后一帧数据缓冲区中提取数据到显示缓冲区
pDoc->GetShowDataFromBuffer();
//启动波形显示线程
threadShowStart.SetEvent();
Sleep(20);//空出一定的时间来显示最后一帧数据
//发终止信号给波形显示线程
threadShowEnd.SetEvent();
return 0;
}
/*----------------------------------------------------------------------------
function: 将采集到的数据进行动态显示的线程函数
parameters:
param 指向视窗的指针
author: 唐富华
date: 2004.5.14
-----------------------------------------------------------------------------*/
UINT ThreadShow(LPVOID param)
{
BOOL KeepRunning=true;
while(KeepRunning)
{
//等待数据采集线程发出的数据显示同步信号
::WaitForSingleObject(threadShowStart.m_hObject,INFINITE);
//收到信号后对采集到的数据进行动态显示
((CSimulationView*)param)->DynamicShowWave(((CSimulationView*)param)->GetDC());
//释放动态显示同步信号
threadShowStart.Unlock();
//等待动态显示终止同步信号
int result = ::WaitForSingleObject(threadShowEnd.m_hObject,0);
//若收到动态显示终止同步信号则线程结束
if(result==WAIT_OBJECT_0)
KeepRunning = false;
}
return 0;
}
IMPLEMENT_DYNCREATE(CSimulationView, CScrollView)
BEGIN_MESSAGE_MAP(CSimulationView, CScrollView)
//{{AFX_MSG_MAP(CSimulationView)
ON_COMMAND(ID_INIT, OnInit)
ON_COMMAND(ID_START, OnStart)
ON_COMMAND(ID_STOP, OnStop)
ON_COMMAND(ID_LOAD, OnLoad)
ON_COMMAND(ID_SIMULATE, OnSimulate)
ON_COMMAND(ID_SHOW_REALDATA, OnShowRealdata)
ON_COMMAND(ID_SHOW_SIMUDATA, OnShowSimudata)
ON_COMMAND(ID_SHOW_SENSORDATA, OnShowSensordata)
ON_WM_KEYDOWN()
ON_COMMAND(ID_APP_EXIT, OnAppExit)
ON_COMMAND(ID_JUDGE, OnJudge)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSimulationView construction/destruction
CSimulationView::CSimulationView()
{
// TODO: add construction code here
m_Pages=0;
m_MaxPages=1;
m_bDataCollect = false;
}
CSimulationView::~CSimulationView()
{
}
BOOL CSimulationView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CScrollView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CSimulationView drawing
void CSimulationView::OnDraw(CDC* pDC)
{
CSimulationDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
//若没有启动数据采集线程,则显示已打开文件数据波形
if(!this->m_bDataCollect)
DrawWave(pDC);
}
void CSimulationView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
CSize sizeTotal;
// TODO: calculate the total size of this view
sizeTotal.cx = sizeTotal.cy = 100;
SetScrollSizes(MM_TEXT, sizeTotal);
}
/////////////////////////////////////////////////////////////////////////////
// CSimulationView diagnostics
#ifdef _DEBUG
void CSimulationView::AssertValid() const
{
CScrollView::AssertValid();
}
void CSimulationView::Dump(CDumpContext& dc) const
{
CScrollView::Dump(dc);
}
CSimulationDoc* CSimulationView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CSimulationDoc)));
return (CSimulationDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CSimulationView message handlers
void CSimulationView::OnInit()
{
// TODO: Add your command handler code here
//清空FIFO
//查询信号发生板是否就绪
//给信号发生板发启动命令
}
void CSimulationView::OnStart()
{
// TODO: Add your command handler code here
CSimulationDoc* pDoc = GetDocument();
//显示保存文件对话框,让用户输入保存采集的重力和剪力数据的文件名
CString szFilter1 = "SR Files (*.SR)|*.SR|All Files (*.*)|*.*||";
CFileDialog SRfdlg(false,_T("please input the filename to save SRData!"),NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter1);
if(SRfdlg.DoModal() ==IDCANCEL)
return;
CString strSRFileName = SRfdlg.GetPathName();
CString szFilter2 = "WT Files (*.WT)|*.WT|All Files (*.*)|*.*||";
CFileDialog WTfdlg(false,_T("please input the filename to save WTData!"),NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter2);
if(WTfdlg.DoModal() ==IDCANCEL)
return;
CString strWTFileName = WTfdlg.GetPathName();
if(!SRFile.Open( strSRFileName, CFile::modeWrite|CFile::modeCreate|CFile::typeBinary)||!WTFile.Open(strWTFileName,CFile::modeWrite|CFile::modeCreate|CFile::typeBinary))
{
MessageBox(_T("Could not open the file:")+strSRFileName+_T(" or ")+strWTFileName);
return;
}
//对读取和显示缓冲区以及读取的数据长度进行初始化
pDoc->m_ReadSRLen=0;
pDoc->m_ReadWTLen=0;
memset(pDoc->m_ReadSRBuffer,0,BUFFERREAD_LEN*sizeof(unsigned short));
memset(pDoc->m_ReadWTBuffer,0,BUFFERREAD_LEN*sizeof(unsigned short));
memset(pDoc->m_ShowSRBuffer,0,BUFFERSHOW_LEN*sizeof(unsigned short));
memset(pDoc->m_ShowWTBuffer,0,BUFFERSHOW_LEN*sizeof(unsigned short));
memset(pDoc->m_ShowCOBuffer,0,BUFFERSHOW_LEN*sizeof(int));
//清空FIFO
_asm
{
mov al,0h
mov dx,1000h
out dx,al
}
//发启动采集命令
_asm
{
mov al,40h
mov dx,1001h
out dx,al
}
//启动数据采集和动态显示线程
pReadThread=AfxBeginThread(ThreadRead,this,THREAD_PRIORITY_TIME_CRITICAL);
pShowThread=AfxBeginThread(ThreadShow,this);
//设置启动数据采集标志
this->m_bDataCollect=true;
}
void CSimulationView::OnStop()
{
//给数据读取和显示线程发终止信号
threadReadEnd.SetEvent();
threadShowEnd.SetEvent();
//设置数据采集终止标志
this->m_bDataCollect=false;
}
void CSimulationView::OnLoad()
{
CSimulationDoc* pDoc = GetDocument();
//提示打开一个剪力数据文件
if(MessageBox(_T("please select a shearing force file to open first!"))==IDCANCEL)
return;
CFileDialog SRfdlg(true);
if(SRfdlg.DoModal() ==IDCANCEL)
return;
CString strSRFileName = SRfdlg.GetPathName();
//提示打开一个重力数据文件
if(MessageBox(_T("please select a gravity file to open secondly!"))==IDCANCEL)
return;
CFileDialog WTfdlg(true);
if(WTfdlg.DoModal() ==IDCANCEL)
return;
CString strWTFileName = WTfdlg.GetPathName();
//从剪力数据文件中读取数据,接着进行中值滤波,然后从数据中获取最大值
if(pDoc->m_pSRData)
{
free(pDoc->m_pSRData);
pDoc->m_pSRData=NULL;
}
pDoc->m_pSRData=pDoc->ReadDataFromFile(&pDoc->m_SRDataLen,strSRFileName);
pDoc->MidValueFilter5(pDoc->m_pSRData,pDoc->m_SRDataLen);
pDoc->m_SRMaxValue=pDoc->GetMaxValue(pDoc->m_pSRData,pDoc->m_SRDataLen);
pDoc->m_pSRShow=pDoc->GetShowData(pDoc->m_pSRData,pDoc->m_SRDataLen);
//从重力数据文件中读取数据,接着进行中值滤波和平滑滤波,然后从数据中获取最大值
if(pDoc->m_pWTData)
{
free(pDoc->m_pWTData);
pDoc->m_pWTData=NULL;
}
pDoc->m_pWTData=pDoc->ReadDataFromFile(&pDoc->m_WTDataLen,strWTFileName);
pDoc->MidValueFilter5(pDoc->m_pWTData,pDoc->m_WTDataLen);
// pDoc->SmoothFilter(pDoc->m_pWTData,pDoc->m_WTDataLen,101);
pDoc->m_WTMaxValue=pDoc->GetMaxValue(pDoc->m_pWTData,pDoc->m_WTDataLen);
pDoc->m_pWTShow=pDoc->GetShowData(pDoc->m_pWTData,pDoc->m_WTDataLen);
pDoc->SmoothFilter(pDoc->m_pWTShow,pDoc->m_WTDataLen/pDoc->m_Interval+1,7);
//根据剪力和重力数据产生合力数据
if(pDoc->m_pCOData)
{
free(pDoc->m_pCOData);
pDoc->m_pCOData=NULL;
}
pDoc->GetCOData();
pDoc->m_COMaxValue=pDoc->GetMaxValue(pDoc->m_pCOData,pDoc->m_CODataLen);
pDoc->m_pCOShow=pDoc->GetShowData(pDoc->m_pCOData,pDoc->m_CODataLen);
pDoc->SmoothFilter(pDoc->m_pCOShow,pDoc->m_CODataLen/pDoc->m_Interval+1,7);
//根据当前视窗大小求得总得显示页数并刷新视窗
CRect rc;
this->GetClientRect(&rc);
this->m_MaxPages=(pDoc->m_SRDataLen/pDoc->m_Interval+1)/rc.Width();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -