?? pc2plcview.cpp
字號:
// PC2PLCView.cpp : implementation of the CPC2PLCView class
//
#include "stdafx.h"
#include "PC2PLC.h"
#include "PC2PLCDoc.h"
#include "PC2PLCView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//定義全局變量
HANDLE hCom; //串口句柄
DWORD ThreadProcWrite(LPVOID pParam); //寫線程函數
DWORD ThreadProcRead(LPVOID pParam); //讀線程函數
OVERLAPPED Wol={0}; //寫操作OVERLAPPED結構變量
OVERLAPPED Rol={0}; //讀操作OVERLAPPED結構變量
HANDLE hThreadWrite; //寫線程句柄
HANDLE hThreadRead; //讀線程句柄
HWND hWnd; //窗口句柄
BYTE myRByte[300]; //存放已讀數據
BYTE myWByte[300]; //存放欲寫數據
long dataRLen; //接收數據的長度
long dataWLen; //發送數據的長度
bool blnError; //錯誤標志,在接收命令代碼中使用
int intWrite=0; //反映寫操作的狀態,0-無意義,1-寫錯誤,2-寫正確
int intRead=0; //反映讀操作的狀態,0-無意義,1-讀錯誤,2-讀正確
/////////////////////////////////////////////////////////////////////////////
// CPC2PLCView
IMPLEMENT_DYNCREATE(CPC2PLCView, CEditView)
BEGIN_MESSAGE_MAP(CPC2PLCView, CEditView)
//{{AFX_MSG_MAP(CPC2PLCView)
ON_COMMAND(ID_SETUP, OnSetup)
ON_COMMAND(ID_RECEIVE, OnReceive)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_UPDATE_COMMAND_UI(ID_RECEIVE, OnUpdateReceive)
ON_COMMAND(ID_OPENCOM, OnOpencom)
ON_UPDATE_COMMAND_UI(ID_SETUP, OnUpdateSetup)
ON_UPDATE_COMMAND_UI(ID_OPENCOM, OnUpdateOpencom)
ON_UPDATE_COMMAND_UI(ID_CLOSECOM, OnUpdateClosecom)
ON_COMMAND(ID_CLOSECOM, OnClosecom)
ON_UPDATE_COMMAND_UI(ID_APP_EXIT, OnUpdateAppExit)
ON_WM_CHAR()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPC2PLCView construction/destruction
CPC2PLCView::CPC2PLCView()
{
// TODO: add construction code here
myCom="COM4"; //默認設置
myBaudRate=CBR_4800;
myfParity=false;
myParity=NOPARITY;
}
CPC2PLCView::~CPC2PLCView()
{
}
BOOL CPC2PLCView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
BOOL bPreCreated = CEditView::PreCreateWindow(cs);
cs.style &= ~(ES_AUTOHSCROLL|WS_HSCROLL); // Enable word-wrapping
return bPreCreated;
}
/////////////////////////////////////////////////////////////////////////////
// CPC2PLCView drawing
void CPC2PLCView::OnDraw(CDC* pDC)
{
CPC2PLCDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
/////////////////////////////////////////////////////////////////////////////
// CPC2PLCView diagnostics
#ifdef _DEBUG
void CPC2PLCView::AssertValid() const
{
CEditView::AssertValid();
}
void CPC2PLCView::Dump(CDumpContext& dc) const
{
CEditView::Dump(dc);
}
CPC2PLCDoc* CPC2PLCView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CPC2PLCDoc)));
return (CPC2PLCDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CPC2PLCView message handlers
void CPC2PLCView::OnSetup()
{
// TODO: Add your command handler code here
CString strStatus;
if(mySetupDlg.DoModal()==IDOK)
{
switch (mySetupDlg.m_Com)
{
case 0:
{
strStatus="COM1";
strStatus+=" ";
myCom="COM1";
break;
}
case 1:
{
strStatus="COM2";
strStatus+=" ";
myCom="COM2";
break;
}
case 2:
{
strStatus="COM3";
strStatus+=" ";
myCom="COM3";
break;
}
case 3:
{
strStatus="COM4";
strStatus+=" ";
myCom="COM4";
break;
}
case 4:
{
strStatus="COM5";
strStatus+=" ";
myCom="COM5";
}
break;
case 5:
{
strStatus="COM6";
strStatus+=" ";
myCom="COM6";
}
break;
}
switch(mySetupDlg.m_BaudRate)
{
case 0:
{
strStatus+="19200";
strStatus+=" ";
myBaudRate=CBR_19200;
break;
}
case 1:
{
strStatus+="9600";
strStatus+=" ";
myBaudRate=CBR_9600;
break;
}
case 2:
{
strStatus+="4800";
strStatus+=" ";
myBaudRate=CBR_4800;
break;
}
case 3:
{
strStatus+="2400";
strStatus+=" ";
myBaudRate=CBR_2400;
break;
}
}
switch(mySetupDlg.m_Parity)
{
case 0:
{
myfParity=false;
myParity=NOPARITY;
strStatus+="N";
strStatus+="-8-1";
break;
}
case 1:
{
myfParity=TRUE;
myParity=ODDPARITY;
strStatus+="O";
strStatus+="-8-1";
break;
}
case 2:
{
myfParity=true;
myParity=EVENPARITY;
strStatus+="E";
strStatus+="-8-1";
break;
}
}
CMainFrame* m_pGetFrame=(CMainFrame*) AfxGetApp()->m_pMainWnd ;
CStatusBar* m_pStatus=&m_pGetFrame->m_wndStatusBar;
m_pStatus->SetPaneText(1,strStatus); //將通信參數顯示在狀態條上
}
}
//*******************************************
//***接收操作代碼*************************
//********************************************
void CPC2PLCView::OnReceive()
{
// TODO: Add your command handler code here
int i,j;
CString strDis,strTemp;
char myChar[20];
BYTE xorByte; //存放奇偶校驗和
PurgeComm(hCom,PURGE_RXCLEAR); //清空接收和發送緩沖區
PurgeComm(hCom,PURGE_TXCLEAR);
myWByte[0]=5;
dataWLen=1;
CEdit& myEdit=this->GetEditCtrl( );
myEdit.SetSel(1000000,1000000);
strDis="";
strDis+="<-- [ENQ] ";
_strdate(myChar);
strDis+=myChar;
strDis+=" ";
_strtime(myChar);
strDis+=myChar;
strDis+="\15\12";
myEdit.ReplaceSel(strDis);
intWrite=0;
if (!myfuncWrite()) //發出ENQ讀數據請求
{
myEdit.SetSel(1000000,1000000);
strDis="";
strDis+=" 通信錯誤\15\12\15\12";
myEdit.ReplaceSel(strDis);
Beep(1000,50);
return;
}
dataRLen=3;
intRead=0;
if(myfuncRead(5)) //讀數據,應該為“ACK,長度,長度取反值”
{
strDis="--> ";
for(i=0;i<=2;i++)
{
strTemp.Format("%02X",myRByte[i]); //將16進制數格式化為2位形式
strDis+=strTemp;
strDis+="|";
}
myEdit.SetSel(1000000,1000000);
strDis+="\15\12";
strDis.MakeUpper();
myEdit.ReplaceSel(strDis); //顯示接收到的數據
}
else//若出錯,說明通信故障,退出此次讀數據操作
{
blnError=true;
myEdit.SetSel(1000000,1000000);
strDis="";
strDis+=" 通信錯誤\15\12\15\12";
myEdit.ReplaceSel(strDis);
Beep(1000,50);
return;
}
for(i=0;i<3;i++) //對數據進行3次校驗
{
if((myRByte[0]==6) && ((myRByte[1]+myRByte[2])==255))
{
blnError=false;
break;
}
else
{
blnError=true;
}
myWByte[0]=21;
dataWLen=1;
intWrite=0;
myEdit.SetSel(1000000,1000000);
strDis="";
strDis+="<-- [NAK]\15\12";
myEdit.ReplaceSel(strDis);
if(!myfuncWrite()) //若校驗未通過,則回應NAK,要求重發
{
blnError=true;
break;
}
dataRLen=3;
intRead=0;
if(myfuncRead(21))//再次讀取數據,應該為“ACK,長度,長度取反值”
{
strDis="--> ";
strTemp.Format("%02X",myRByte[0]);
strDis+=strTemp;
strDis+="|";
strTemp.Format("%02X",myRByte[1]);
strDis+=strTemp;
strDis+="|";
strTemp.Format("%02X",myRByte[2]);
strDis+=strTemp;
myEdit.SetSel(1000000,1000000);
strDis+="\15\12";
strDis.MakeUpper();
myEdit.ReplaceSel(strDis);//
}
else
{
blnError=true;
myEdit.SetSel(1000000,1000000);
strDis="";
strDis+=" 通信錯誤\15\12\15\12";
strDis.MakeUpper();
myEdit.ReplaceSel(strDis);
Beep(1000,50);
return;
}
}
if (blnError)//若出錯,說明通信存在故障,則退出本次操作
{
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";
strDis.MakeUpper();
myEdit.ReplaceSel(strDis);
Beep(1000,50);
return;
}
//回應ACK成功,等待接收數據
dataRLen=myRByte[1]+1;
for(i=0;i<3;i++) //若1次未讀出正確數據,則重新操作,共循環3次
{
intRead=0;
if(myfuncRead(21))
{
strDis="--> ";
xorByte=0;
for(j=0;j<=dataRLen-2;j++)
{
strTemp.Format("%02X",myRByte[j]);
strDis+=strTemp;
strDis+="|";
xorByte^=myRByte[j];
}
strTemp.Format("%02X",myRByte[dataRLen-1]);
strDis+=strTemp;
myEdit.SetSel(1000000,1000000);
strDis+="\15\12";
strDis.MakeUpper();
myEdit.ReplaceSel(strDis); //顯示接收到的數據
if(myRByte[dataRLen-1]==xorByte) //校驗數據
{
blnError=false;
break;
}
else
{
blnError=true;
}
}
else
{
blnError=true;
break;
}
myWByte[0]=21;
dataWLen=1;
intWrite=0;
myEdit.SetSel(1000000,1000000);
strDis="";
strDis+="<-- [NAK]\15\12";
strDis.MakeUpper();
myEdit.ReplaceSel(strDis);
if(!myfuncWrite()) //數據校驗出錯,響應NAK,要求重發
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -