⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 monitordoc.cpp

📁 模拟了tec2000的所有功能
💻 CPP
📖 第 1 页 / 共 2 页
字号:
{
	// 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 + -