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

📄 pc2plcview.cpp

📁 本程序主要通过VC实现计算机与西门子S7-200间的串口通讯。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		{
			blnError=true;
			break;
		}

	}
	if (blnError)//若blnError被置1,说明通信存在故障,则退出本次操作
	{
		myEdit.SetSel(1000000,1000000);
		strDis="";
		strDis+="   通信错误\15\12\15\12";
		strDis.MakeUpper();
		myEdit.ReplaceSel(strDis);
		Beep(1000,50);
		blnError=false;
		return;
	}
	//数据已经读回,并且已经校验正确
	myWByte[0]=6;                          //回应ACK
	dataWLen=1;
	myEdit.SetSel(1000000,1000000);
	strDis="";
	strDis+="<-- [ACK]\15\12";
	strDis.MakeUpper();
	myEdit.ReplaceSel(strDis);
	intWrite=0;
	if (!myfuncWrite())
	{
		myEdit.SetSel(1000000,1000000);
		strDis="";
		strDis+="   通信错误\15\12\15\12";
		myEdit.ReplaceSel(strDis);
		Beep(1000,50);
		return;
	}
	myEdit.SetSel(1000000,1000000);
	strDis="";
	strDis+="   接收完毕!\15\12\15\12";
	myEdit.ReplaceSel(strDis);           //显示成功信息
	Beep(1000,50);
	
}

int CPC2PLCView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CEditView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here
	CEdit& myEdit=this->GetEditCtrl( );
	myEdit.SetReadOnly (true);          //将显示区域设为只读
	hWnd=GetSafeHwnd();                 //获取当前窗口的句柄
	blnOpened=false;
	return 0;
}

//*****************************
//****读线程函数****************
//*****************************
DWORD  ThreadProcRead(LPVOID pParam)
{
	
	CString myStr;
	DWORD dwRes;
	DWORD dwRead;                      //实际读出的字节数
	intRead=0;
	Rol.hEvent=CreateEvent(NULL,       //创建Rol的hEvent成员为无信号状态
			TRUE, 
			FALSE, 
			NULL);
	if (Rol.hEvent == NULL)
	{
		AfxMessageBox("hEvent空");
		intRead=1;
         return -1;
	}
	if (ReadFile(hCom,               //串口句柄
			&myRByte,                //存放读取数据
			dataRLen,                //欲读取的字节数
			NULL,
			&Rol))                   //指向创建hCom时的Rol的指针
	{
		intRead=2;

         //在这里加入处理已读取数据的代码,已读取数据存放在myRByte数组中。
	}
	else
	{
		dwRes = WaitForSingleObject(Rol.hEvent, 
				2000);              //设置2秒的超时
		switch(dwRes)
		{
		case WAIT_OBJECT_0:
			 if (!GetOverlappedResult(hCom, 
					&Rol, 
					&dwRead,        //实际读出的字节数
					TRUE))          //TRUE表示直到操作完成该函数才返回
			 {   
				 //操作失败,可以使用GetLastError()函数获取错误信息。
				intRead=1;

			}
			else
			{
			    //操作成功完成,数据读出,并存放到myRByte数组中。
                //在这里加入处理数据的代码
				intRead=2;
			 }
			 break;
		case WAIT_TIMEOUT:
			//读操作失败,原因是读超时。
			intRead=1;
			break;
		default:
			 //这里可以加入默认情况下的处理代码。
			 intRead=1;
			 break;
		}
	}
	CloseHandle(Rol.hEvent);
	return 0;
}

//*****************************
//****写线程函数****************
//*****************************
DWORD  ThreadProcWrite(LPVOID pParam)
{
	CString myStr;
	DWORD dwRes;
	DWORD dwWrite;
	intWrite=0;
	Wol.Internal=0;                //设置OVERLAPPED结构Wol
	Wol.InternalHigh=0;
	Wol.Offset=0;
	Wol.OffsetHigh=0;
	Wol.hEvent=CreateEvent(NULL,   //创建Wol的hEvent成员为无信号状态
         TRUE,
         FALSE,
         NULL);
	if (Wol.hEvent == NULL)
	{
		AfxMessageBox("hEvent空");
		intWrite=1;
         return -1;
	}
	if (WriteFile(hCom,           //串口句柄
			&myWByte,             //存放待发送数据
			dataWLen,             //欲发送的字节数
			NULL,
			&Wol))                //指向创建hCom时的Wol的指针
	{
         //在这里加入成功发送的处理代码。
		intWrite=2;

	}
	else
	{
		dwRes = WaitForSingleObject(Wol.hEvent,
				 500);           //设置写超时500ms
		switch(dwRes)
		{
		case WAIT_OBJECT_0:
			 if (!GetOverlappedResult(hCom, 
					&Wol, 
					&dwWrite, 
					TRUE))
			 {   
				intWrite=1;
				//操作失败,可以使用GetLastError()函数获取错误信息。
			 }
			 else
			 {
				//发送数据成功
				intWrite=2;
				//在这里加入发送成功的处理代码
			 }
			 break;
		case WAIT_TIMEOUT:
			//发送失败,原因是发送超时
			intWrite=1;
			break;
		default:
			//这里可以加入默认情况下的处理代码。
			intWrite=1;
			break;
		}
	}
	CloseHandle(Wol.hEvent);
	return 0;
}

void CPC2PLCView::OnDestroy() 
{
	CEditView::OnDestroy();
	if(!(hCom==NULL))
	{
		CloseHandle(hCom);           //关闭串口句柄
	}
	// TODO: Add your message handler code here
	
}

bool  CPC2PLCView::myfuncWrite()
{
	//写串口操作
	DWORD dwThreadID;//
	DWORD dwParam;
	int	 i;
	for(i=0;i<3;i++)
	{
		hThreadWrite=CreateThread(NULL,
			0,
			(LPTHREAD_START_ROUTINE )ThreadProcWrite, //写线程函数名称
			&dwParam,
			0,                                        //创建线程后,立即执行该线程
			&dwThreadID);
		if (hThreadWrite==NULL)
		{
			AfxMessageBox("写线程创建失败!");
			intWrite=1;
			return false;
		}
		while (intWrite==0)
		{
			Sleep(100);                              //等待写操作结果
		}
		if (intWrite==2)
		{
			return true;
		}
	}
	
	return false;
}

bool	CPC2PLCView::myfuncRead(BYTE ackChar)
{
	//读串口操作代码
	DWORD dwThreadID;
	DWORD dwParam;
	CString strDis;
	int i;
	for(i=0;i<3;i++)
	{
		hThreadRead=CreateThread(NULL,
				0,
				(LPTHREAD_START_ROUTINE )ThreadProcRead,//读线程函数名称
				&dwParam,
				0,                                      //创建线程后,立即执行该线程
				&dwThreadID);
		if (hThreadRead==NULL)
		{
			AfxMessageBox("读线程创建失败!");
			intRead=1;
			return false;
		}
		while (intRead==0)
		{
			Sleep(100);                                //等待读操作结果
		}
		if (intRead==2)
		{
			return true;
		}
		else
		{
			myWByte[0]=ackChar;                       //发送ENQ或NAK(ascii码为5或21)
			dataWLen=1;
			CEdit& myEdit=this->GetEditCtrl( );
			myEdit.SetSel(1000000,1000000);
			strDis="";
			switch(ackChar)
			{
			case 5:
				{
				strDis+="<-- [ENQ]\15\12";
				break;
				}
			case 21:
				{
				strDis+="<-- [NAK]\15\12";
				break;
				}
			}
			myEdit.ReplaceSel(strDis);
			if(!myfuncWrite())
			{
				return false;
			}
		}
	}
	return false;

}



void CPC2PLCView::OnUpdateReceive(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	//根据串口是否打开,决定是否允许“接收”命令
	if (blnOpened)
	{
		pCmdUI->Enable(true);
	}
	else
	{
		pCmdUI->Enable(false);
	}
}

void CPC2PLCView::OnOpencom() 
{
	// TODO: Add your command handler code here
	CString strDis;
	CEdit& myEdit=this->GetEditCtrl( );
	hCom=CreateFile(myCom,                            //创建串口COM2
		GENERIC_READ | GENERIC_WRITE, 
		0,
		NULL,
		OPEN_EXISTING, 
		FILE_ATTRIBUTE_NORMAL| FILE_FLAG_OVERLAPPED, //使用重叠方式
		 NULL );
	if( hCom !=INVALID_HANDLE_VALUE) 
	{
		SetupComm(hCom,1024,512);
		DCB myDCB;
		GetCommState( hCom, &myDCB );
		myDCB.BaudRate=myBaudRate;
		myDCB.fBinary=TRUE;
		myDCB.fParity=myfParity;
		myDCB.ByteSize=8;
		myDCB.Parity=myParity;
		myDCB.StopBits=ONESTOPBIT;
		SetCommState(hCom,&myDCB);

		//显示串口成功打开
		myEdit.SetReadOnly (true);
		myEdit.SetSel(1000000,1000000);
		strDis=myCom;
		strDis+="打开成功!\15\12\15\12";
		myEdit.ReplaceSel(strDis);
		blnOpened=true;
	}
	else
	{
		//显示串口打开失败
		myEdit.SetReadOnly (true);
		myEdit.SetSel(1000000,1000000);
		strDis=myCom;
		strDis+="打开失败!\15\12\15\12";
		myEdit.ReplaceSel(strDis);
		blnOpened=false;
	}
}

void CPC2PLCView::OnUpdateSetup(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	//根据串口是否打开,决定是否允许“设置”命令
	if (!blnOpened)
	{
		pCmdUI->Enable(true);
	}
	else
	{
		pCmdUI->Enable(false);
	}
}

void CPC2PLCView::OnUpdateOpencom(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	//根据串口是否打开,决定是否允许“打开”命令
	if (!blnOpened)
	{
		pCmdUI->Enable(true);
	}
	else
	{
		pCmdUI->Enable(false);
	}
}

void CPC2PLCView::OnUpdateClosecom(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	//根据串口是否打开,决定是否允许“关闭”命令
	if (blnOpened)
	{
		pCmdUI->Enable(true);
	}
	else
	{
		pCmdUI->Enable(false);
	}
	
}

void CPC2PLCView::OnClosecom() 
{
	// TODO: Add your command handler code here
	if ((blnOpened) && (hCom!=NULL))
	{
		CloseHandle(hCom);

		CString strDis;                         //显示串口成功关闭
		CEdit& myEdit=this->GetEditCtrl( );
		myEdit.SetReadOnly (true);
		myEdit.SetSel(1000000,1000000);
		strDis=myCom;
		strDis+="  已关闭!\15\12\15\12";
		myEdit.ReplaceSel(strDis);
		blnOpened=false;
	}
	
}

void CPC2PLCView::OnUpdateAppExit(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	//根据串口是否打开,决定是否允许“退出”命令
	if (blnOpened)
	{
		pCmdUI->Enable(false);
	}
	else
	{
		pCmdUI->Enable(true);
	}
}

void CPC2PLCView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// TODO: Add your message handler code here and/or call default
	
	CEditView::OnChar(nChar, nRepCnt, nFlags);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -