📄 monitordoc.cpp
字号:
{
// TODO: Add your command handler code here
//监控线程挂起
m_pThread->SuspendThread();
int startaddr,endaddr,memlen;
BYTE temp,temp1,temp2;
CSetAddrDlg StartAndEnd;
char *buffer1,*buffer2;
in:
if(StartAndEnd.DoModal()==IDOK)
{
buffer1=StartAndEnd.m_strStartAddr.GetBuffer(0);
//如果输入的地址不足4位,如23,则补足4位为0023,否则编译程序会理解为2300,导致错误
if(strlen(buffer1)<4)buffer1=FillZero(buffer1);
//将地址分解为两部分,前两个字节为高位,后两个为低位
sscanf(buffer1,"%02X%02X",&temp1,&temp2);
startaddr=(int)temp1*256+(int)temp2;
//同上
buffer2=StartAndEnd.m_strEndAddr.GetBuffer(0);
if(strlen(buffer2)<4)buffer2=FillZero(buffer2);
sscanf( buffer2,"%02X%02X",&temp1,&temp2);
endaddr=(int)temp1*256+(int)temp2;
//检验输入是否合法
if(endaddr<startaddr)
{
AfxMessageBox("首地址应小于末地址");
goto in;
}
if(endaddr>0x8000)
{
AfxMessageBox("末地址应该不大于8000H");
goto in;
}
//获取数据字长度(十进制)
memlen=endaddr-startaddr+1;
}
else{
m_pThread->ResumeThread();
return;
}
//打开对话框,用户输入文件名,用于保存导出的内存内容
char *TypeStr="COD Files (*.cod)|*.cod; *.cod|All Files (*.*)|*.*||";
CFile File;
CFileDialog OpenFile(FALSE,".cod",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
TypeStr,NULL);
if (OpenFile.DoModal() == IDOK)
File.Open((LPCTSTR)OpenFile.GetPathName(), CFile::modeWrite|CFile::modeCreate);
else
{
m_pThread->ResumeThread();
return;
}
//将文件头01写入文件
temp=0x01;
File.Write(&temp,1);
//将4位的地址拆分成高位和低位部分,写入文件
sscanf(buffer1,"%02X%02X",&temp1,&temp2);
File.Write(&temp2,1);
File.Write(&temp1,1);
//将数据字长度转换成两部分,高位字节和低位字节,写入文件
temp1=(memlen&0xff00)>>8;
temp2=(memlen&0x00ff);
File.Write(&temp2,1);
File.Write(&temp1,1);
//将字符串格式化,以便与下面的cs作加运算
StartAndEnd.m_strStartAddr.Format("%s",buffer1);
StartAndEnd.m_strEndAddr.Format("%s",buffer2);
//形成导出命令"S 首地址 末地址"
CString cs;
cs="S "+StartAndEnd.m_strStartAddr+" "+StartAndEnd.m_strEndAddr+'\r';
//清空串口输入,输出缓冲区
PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);
char *command=cs.GetBuffer(0);
//将导出命令"S 首地址 末地址"写入串口,调用TEC2000的发送文件子程序SEND()
for(unsigned int i=0;i<strlen(command);i++)
{
WritePort(&command[i],1); //写入串口
WaitDataArrival(); //等待确认到达
ReadPort(&command[i],1); //读确认
}
Sleep(20);
ReadPort((char*)&temp,1); //将一个无关字节读出,出现该字节原因未知
for( int j=0;j<2*memlen;j++)
{
WaitDataArrival(); //等待输入缓冲区接收到新字符
ReadPort((char*)&temp,1); //读串口
File.Write(&temp,1); //写入文件
WritePort((char*)&temp,1); //写回确认
}
File.Close();
cs.Format("%d",2*memlen);
cs="Tec2000导出了"+cs+"个字节";
AfxMessageBox(cs);
//清空输入输出缓冲区
PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);
//监控线程恢复运行
m_pThread->ResumeThread();
}
void CMonitorDoc::OnUpdateFileExport(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable(m_bConnected);
}
//PC--->TEC,文件导入
void CMonitorDoc::OnFileImport()
{
//TODO: Add your command handler code here
//监控线程挂起
m_pThread->SuspendThread();
/*打开浏览框,用户选择文件作为导入到tec2000的文件*/
char *TypeStr="COD Files (*.cod)|*.cod; *.cod|All Files (*.*)|*.*||";
CFile File;
CFileDialog OpenFile(TRUE,".cod",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
TypeStr,NULL);
if (OpenFile.DoModal() == IDOK)
File.Open((LPCTSTR)OpenFile.GetPathName(), CFile::modeRead);//以只读方式打开文件
else
{
m_pThread->ResumeThread();
return;
}
WORD temp;
BYTE temp1,temp2;
CString cs="L "; //存放导入命令“L 首地址 数据字长度"
//文件长度(以字节为单位)
unsigned int Length=File.GetLength();
//将01读出
File.Read(&temp,1);
//将首地址读出
File.Read(&temp1,1);
File.Read(&temp2,1);
temp=(int)temp2*256+(int)temp1;
char a[10];
//将首地址转换成4位(16进制形式)
CString cs1;
cs1.Format("%d",temp);
wsprintf(a,"%04X",temp);
cs1.Format("%s",a);
cs=cs+cs1+" ";
//将字长度从文件读出
File.Read(&temp1,1);
File.Read(&temp2,1);
temp=(int)temp2*256+(int)temp1;
//将字长度转换成4位(16进制形式)
cs1.Format("%d",temp);
wsprintf(a,"%04X",temp);
cs1.Format("%s",a);
//形成最终导入命令"L 首地址 字长度"
cs=cs+cs1+'\r';
Length=Length-5; //文件长度减去5
//清空串口输入输出缓冲区
PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);
char*command=cs.GetBuffer(0);
//将导入命令“L 首地址 字长度"写入串口,调用TEC2000的接收文件子程序RECV()
for(unsigned int i=0;i<strlen(command);i++)
{
WritePort(&command[i],1);
WaitDataArrival();
ReadPort(&command[i],1);
}
//将文件主体逐字节写入串口
for(i=0;i<Length;i++)
{
File.Read(&temp,1);
WritePort((char*)&temp,1);
WaitDataArrival();
ReadPort((char*)&temp,1);
}
//关闭文件,做一些善后处理
File.Close();
cs.Format("%d",Length);
cs="Tec2000导入了"+cs+"个字节";
AfxMessageBox(cs);
//清空输入,输出缓冲区
PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);
//监控线程恢复运行
m_pThread->ResumeThread();
}
void CMonitorDoc::OnUpdateFileImport(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable(m_bConnected);
}
//用户配置串口参数
void CMonitorDoc::OnSettings()
{
// TODO: Add your command handler code here
CSetupDlg dlg;
CString str;
dlg.m_bConnected=m_bConnected;
if(dlg.DoModal()==IDOK)
{
m_sPort=dlg.m_sPort;
m_nBaud=atoi(dlg.m_sBaud);
m_nDataBits=atoi(dlg.m_sDataBits);
CString cs=dlg.m_nStopBits;
if(cs=="1") m_nStopBits=0;
if(cs=="1.5") m_nStopBits=1;
if(cs=="2") m_nStopBits=2;
cs=dlg.m_nParity;
if(cs=="None") m_nParity=0;
if(cs=="Even") m_nParity=1;
if(cs=="Odd") m_nParity=2;
if(m_bConnected)
if(!ConfigConnection())
AfxMessageBox("Can't finish the settings!");
}
}
void CMonitorDoc::OnUpdateSettings(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable(!m_bConnected);
}
//等待串口输入缓冲区收到新字符
void CMonitorDoc::WaitDataArrival()
{
SetCommMask(m_hComm,EV_RXCHAR);
DWORD dwMask=0;
while((dwMask&EV_RXCHAR)!=EV_RXCHAR)
WaitCommEvent(m_hComm,&dwMask,NULL);
}
//将字符串补足为四位,如23补足为0023
char * CMonitorDoc::FillZero(char *str)
{
char *buffer=str;
int len=strlen(str)-1;
buffer[4]='\0';
for(int i=3;i>=0;i--)
if(len>=0)
buffer[i]=str[len--];
else
buffer[i]='0';
return buffer;
}
//监控线程函数
UINT CommThread(LPVOID pParam)
{
OVERLAPPED ov;
DWORD dwMask,dwTrans;
COMSTAT ComStat;
DWORD dwErrorFlags;
CMonitorDoc *pDoc=(CMonitorDoc*)pParam;
memset(&ov,0,sizeof(OVERLAPPED)); //将OVERLAPPED结构清零
ov.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
if(ov.hEvent==NULL)
{
AfxMessageBox("Can't create event object!");
return (UINT)-1;
}
while(pDoc->m_bConnected)
{ //清除缓冲区错误标志,得到缓冲区相关状态(有无字符)
ClearCommError(pDoc->m_hComm,&dwErrorFlags,&ComStat);
if(ComStat.cbInQue)
{ //如果缓冲区有数据,无限等待WM_COMMNOTIFY被处理(m_hPostMsgEvent置为有信号状态)
WaitForSingleObject(pDoc->m_hPostMsgEvent,INFINITE);
//将m_hPostMsgEvent置为无信号状态,下一次传输WM_COMMNOTIFY消息时使用
ResetEvent(pDoc->m_hPostMsgEvent);
//通知视图,让其接收缓冲区字符
PostMessage(pDoc->m_hTermWnd,WM_COMMNOTIFY,EV_RXCHAR,0);
continue;
}
dwMask=0;
//若缓冲区没有字符,等待字符到达
if(!WaitCommEvent(pDoc->m_hComm,&dwMask,&ov))
{ //如果是因为进行I/O后台处理导致函数返回,则调用GetOverlappedResult()等待操作完成
if(GetLastError()==ERROR_IO_PENDING)
GetOverlappedResult(pDoc->m_hComm,&ov,&dwTrans,TRUE);
else
{
CloseHandle(ov.hEvent);
return (UINT)-1;
}
}
}
CloseHandle(ov.hEvent);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -