📄 sl_plcview.cpp
字号:
// SL_PLCView.cpp : implementation of the CSL_PLCView class
//
#include "stdafx.h"
#include "SL_PLC.h"
#include "SL_PLCDoc.h"
#include "SL_PLCView.h"
#include "hex2a.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const short STX_start =0x02;
const short ETX_end =0x03;
const short ENQ_request =0x05;
const short ACK_reply =0x06;
const short CMD0_read =0x30;
const short CMD1_write =0x31;
const short CMD7_ForceON =0x37;
const short CMD8_ForceOFF=0x38;
BOOL volatile g_bContinue=FALSE;
/////////////////////////////////////////////////////////////////////////////
// CSL_PLCView
IMPLEMENT_DYNCREATE(CSL_PLCView, CFormView)
BEGIN_MESSAGE_MAP(CSL_PLCView, CFormView)
//{{AFX_MSG_MAP(CSL_PLCView)
ON_BN_CLICKED(IDC_START, OnStart)
ON_BN_CLICKED(IDC_READPLC, OnReadPlc)
ON_BN_CLICKED(IDC_WRITEPLC, OnWritePlc)
ON_BN_CLICKED(IDC_CLOSE_COM, OnCloseCom)
ON_BN_CLICKED(IDC_ON, OnOn)
ON_BN_CLICKED(IDC_OFF, OnOff)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CFormView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CFormView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CFormView::OnFilePrintPreview)
END_MESSAGE_MAP()
/*BEGIN_EVENTSINK_MAP(CSL_PLCView, CView)
//{{AFX_EVENTSINK_MAP(CWaterCut1View)
ON_EVENT(CSL_PLCView, ID_CTRCOMM, 1 , ReadFromPLC, VTS_NONE)
//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()
*/
/////////////////////////////////////////////////////////////////////////////
// CSL_PLCView construction/destruction
CSL_PLCView * pView=NULL;
UINT ThreadForceOn(LPVOID lparam)
{
/* pView=(CSL_PLCView *)lparam;
int i;
char sum_Check[2];
char read_buffer;
int Sum=0;
int Sum_Check=0;
char ON_Address[]={0x30,0x30,0x38,0x30};
pView->m_com.SetOutput(COleVariant((CString)ENQ_request));//向PLC发送ENQ请求
while(g_bContinue==FALSE)
Sleep(500);
if(pView->m_data[0]!=ACK_reply) return 0 ;
// g_bContinue=FALSE;
pView->m_com.SetOutput(COleVariant((CString)STX_start));
pView->m_com.SetOutput(COleVariant((CString)CMD7_ForceON));
Sum+=1;//CMD7_ForceON;
for(i=0;i<4;i++)
{
pView->m_com.SetOutput(COleVariant((CString)ON_Address[i]));
//发送起始元地址的ASCII代码
//Sum+=ON_Address[i];
Sum++;
}
pView->m_com.SetOutput(COleVariant(ETX_end));//发送"结束"标志代码
//Sum+=ETX_end;
Sum+=1;
//changetoASCII(Sum_Check,Sum); //将“和”转化成ASCII代码
Sum_Check=HexToASCII(Sum);
pView->m_com.SetOutput(COleVariant((CString)54));//Sum_Check));
Sleep(1000);//等待PLC响应
//Serial.ReadData(&read_buffer,1);
//ReadFromPLC();
if(pView->m_data[0]==ACK_reply)//read_BUFFER==ACK_reply)
{
AfxMessageBox("ON 操作 OK!");
}
else
{
AfxMessageBox("ON 操作失败!");
}
*/
return 1;
}
CSL_PLCView::CSL_PLCView()
: CFormView(CSL_PLCView::IDD)
{
//{{AFX_DATA_INIT(CSL_PLCView)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// TODO: add construction code here
m_bCreated=FALSE;
}
CSL_PLCView::~CSL_PLCView()
{
}
void CSL_PLCView::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CSL_PLCView)
DDX_Control(pDX, IDC_GEAR1, m_ctrGear1);
//}}AFX_DATA_MAP
}
BOOL CSL_PLCView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CFormView::PreCreateWindow(cs);
}
void CSL_PLCView::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
GetParentFrame()->RecalcLayout();
ResizeParentToFit();
}
/////////////////////////////////////////////////////////////////////////////
// CSL_PLCView printing
BOOL CSL_PLCView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CSL_PLCView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CSL_PLCView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
void CSL_PLCView::OnPrint(CDC* pDC, CPrintInfo* /*pInfo*/)
{
// TODO: add customized printing code here
}
/////////////////////////////////////////////////////////////////////////////
// CSL_PLCView diagnostics
#ifdef _DEBUG
void CSL_PLCView::AssertValid() const
{
CFormView::AssertValid();
}
void CSL_PLCView::Dump(CDumpContext& dc) const
{
CFormView::Dump(dc);
}
CSL_PLCDoc* CSL_PLCView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CSL_PLCDoc)));
return (CSL_PLCDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CSL_PLCView message handlers
void CSL_PLCView::OnStart()
{
// TODO: Add your control notification handler code here
if (m_ctrGear1.Load(MAKEINTRESOURCE(IDR_GEAR1),_T("GIF")))
m_ctrGear1.Draw();
}
void CSL_PLCView::InitComm(int port)
{
if(m_bCreated==FALSE)
{
WCHAR pwchLicenseKey[] =
{
0x0043, 0x006F, 0x0070, 0x0079, 0x0072, 0x0069,
0x0067, 0x0068, 0x0074, 0x0020, 0x0028, 0x0063,
0x0029, 0x0020, 0x0031, 0x0039, 0x0039, 0x0034,
0x0020
};
BSTR bstrLicense = ::SysAllocStringLen(pwchLicenseKey,
sizeof(pwchLicenseKey)/sizeof(WCHAR));
m_com.Create(NULL,WS_VISIBLE, CRect(10,10,10,10),this,
ID_CTRCOMM, NULL, FALSE, bstrLicense);
::SysFreeString(bstrLicense);
m_bCreated=TRUE;
}
if(!m_com.GetPortOpen())
{
m_com.SetCommPort(port);
m_com.SetSettings("9600,e,7,1");//e-偶校验 7-数据位 1个停止位
m_com.SetInBufferSize(1024);
m_com.SetOutBufferSize(512);
m_com.SetInBufferCount(0);
m_com.SetInputMode(1);
m_com.SetInputLen(0);
m_com.SetRThreshold(1);
m_com.SetPortOpen(TRUE);
}
}
char CSL_PLCView::HexChar(char c)//检测一个字符是不是十六进制字符,若是返回相应的值,否则返回0x10;
{
if((c>='0')&&(c<='9'))
return c-0x30;
else if((c>='A')&&(c<='F'))
return c-'A'+10;
else if((c>='a')&&(c<='f'))
return c-'a'+10;
else return 0x10;
}
void CSL_PLCView::ReadFromPLC()
{
VARIANT m_input1;
COleSafeArray m_input2;
long length=0;
CString str,str1;
str1.Empty();
memset(m_data,205,2);
// if(m_com.GetCommEvent()==2)
{
m_input1=m_com.GetInput();
m_input2=m_input1;
length=m_input2.GetOneDimSize();
if (length==0) return;
for(long i=0;i<length;i++)
m_input2.GetElement(&i,m_data+i);
m_com.SetInBufferCount(0);//清空接收缓冲区
g_bContinue=TRUE;
}
// return length;
}
void CSL_PLCView::SendForReadPLC()
{
int i;
char senddatasum_CHECK[2];
char readdatasum_CHECK[2];
char total_BYTES[2]={0x31,0x32};
char readdatasum_check[2];
char m_readAddress[4]={0x30,0x30,0x38,0x30};
int readdata_sum=0;
int datasum_check=0;
int read_bytes=0;
int totalDATABYTES=0;
InitComm(1);//OPEN COM1
m_com.SetOutput(COleVariant((CString)ENQ_request));//向PLC发送ENQ请求
Sleep(1000);
if(m_data[0]!=ACK_reply) return ;
m_com.SetOutput(COleVariant((CString)STX_start));//向PLC发送“开始”标志代码
m_com.SetOutput(COleVariant((CString)CMD0_read));//发送“读”命令代码datasum_check+=CMD0_read
for(i=0;i<4;i++)
{
m_com.SetOutput(COleVariant((CString)m_readAddress[i]));
//发送起始元地址的ASCII代码
datasum_check+=m_readAddress[i];
}
totalDATABYTES=HexToASCII(read_bytes);//将字节数转化成ascii代码
for(i=0;i<2;i++)
{
//发送元件字节数的ASCII代码
m_com.SetOutput(COleVariant((CString)total_BYTES[i]));
datasum_check+=total_BYTES[i];
}
m_com.SetOutput(COleVariant((CString)ETX_end));
datasum_check+=ETX_end;//注意 datasum_check
//changetoASCII(senddatasum_CHECK,senddatasum_CHECK);//将字节数转化成ascii代码
// senddatasum_CHECK=HexToASCII(&senddatasum_CHECK);
//将“和”转化成ASCII代码
for(i=0;i<2;i++)
{
m_com.SetOutput(COleVariant((CString)senddatasum_CHECK[i]));
}
Sleep(1000);//等待PLC响应
//Serial.ReadData(&read_BUFFER,1); wsf
//wsf read_bytes=ReadFromPLC();//可注释掉,因是事件驱动
if(m_data[0]==STX_start)
{
readdata_sum=0;
for(i=0;i<2*read_bytes;i++)
{
// Serial.ReadData(Read_char[i],1);//读read_bytes个字节
//ReadFromPLC();
readdata_sum+=m_data[i];//Read_char[i];
}
// serial.ReadData(&read_BUFFER,1);
ReadFromPLC();
if(m_data[0]==ETX_end)//read_BUFFER==ETX_end
{
// Serial.ReadData(readdatasum_CHECK,2);//读入得“和”的低2位ASCII码
ReadFromPLC();
readdata_sum+=ETX_end;
}
//changetoASCII(readdatasum_check,readdata_sum);//将字节数转化成ascii代码
// readdatasum_check=HexToASCII(readdata_sum);
//将计算得到的“和”转化位ascii码
if(*readdatasum_CHECK==*readdatasum_check)//“和”校验
{
AfxMessageBox("数据读出成功!");
}
else
{
AfxMessageBox("校验错误!");
}
}
}
void CSL_PLCView::SendForWritePLC()
{
char m_dataAddress[]={0x30,0x30,0x38,0x30};
int i=0,uTmp1;
char total_BYTES[2]={0x31,0x32};
char sum_Check[2]={0x30,0x30};
int sumCheck=0;
int bytesnumber=0;
int total_DATABYTES=0;
char Write_ASC[]={0x01,0x00,0x00,0x00,0x00,0X00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
InitComm(1);//OPEN COM1
m_com.SetOutput(COleVariant((CString)ENQ_request));//向PLC发送ENQ请求
g_bContinue=FALSE;
int nTimers=0;
while(g_bContinue==FALSE)
{
ReadFromPLC();
Sleep(500);
nTimers++;
if(nTimers==5 && g_bContinue==FALSE)return;
}
if(m_data[0]!=ACK_reply) return ;
m_com.SetOutput(COleVariant((CString)STX_start));//向PLC发送“开始”标志代码
sumCheck=0;
m_com.SetOutput(COleVariant((CString)CMD1_write));//发送“读”命令代码datasum_check+=CMD0_read
sumCheck+=CMD1_write;
for(i=0;i<4;i++)
{
m_com.SetOutput(COleVariant((CString)m_dataAddress[i]));
//发送起始元地址的ASCII代码
sumCheck+=m_dataAddress[i];
}
total_DATABYTES=HexToASCII(sumCheck);
for(i=0;i<2;i++)
{
//发送元件字节数的ASCII代码
m_com.SetOutput(COleVariant((CString)total_BYTES[i]));
sumCheck+=total_BYTES[i];
}
for(i=0;i<bytesnumber*2;i++)
{
//发送要写入的数据的ASCII码
m_com.SetOutput(COleVariant((CString)Write_ASC[i]));
sumCheck+=Write_ASC[i];
}
m_com.SetOutput(COleVariant((CString)ETX_end));//发送"结束"标志代码
sumCheck+=ETX_end;
//将“和”转化成ASCII代码
uTmp1=sumCheck & 0x0f;
sum_Check[1]=HexToASCII(uTmp1);//2-0x32;
uTmp1=(sumCheck>>4) & 0x0f;
sum_Check[0]=HexToASCII(uTmp1);
for(i=0;i<2;i++)
m_com.SetOutput(COleVariant((CString)sum_Check[i]));
g_bContinue=FALSE;
nTimers=0;
while(g_bContinue==FALSE)
{
ReadFromPLC();
Sleep(500);
nTimers++;
if(nTimers==5 && g_bContinue==FALSE)return;
}
//Serial.ReadData(&read_finishBUFFER,1);
if(m_data[0]==ACK_reply)
{
AfxMessageBox("写入数据成功!");
}
else
{
AfxMessageBox("写入数据失败!");
}
}
void CSL_PLCView::ForceOnOperation(char * ON_Address)
{
int i;
char sum_Check[2]={0x30,0x30};
int Sum=0,uTmp1;
int Sum_Check=0;
int nTimers=0;
InitComm(1);
m_com.SetOutput(COleVariant((CString)ENQ_request));//向PLC发送ENQ请求
while(g_bContinue==FALSE)
{
ReadFromPLC();
Sleep(500);
nTimers++;
if(nTimers==5 && g_bContinue==FALSE)return;
}
if(m_data[0]!=ACK_reply)
return ;
g_bContinue=FALSE;
m_com.SetOutput(COleVariant((CString)STX_start));
m_com.SetOutput(COleVariant((CString)CMD7_ForceON));
Sum+=CMD7_ForceON;
for(i=0;i<4;i++)
{
m_com.SetOutput(COleVariant((CString)ON_Address[i]));
//发送起始元地址的ASCII代码
Sum+=ON_Address[i];
}
m_com.SetOutput(COleVariant((CString)ETX_end));//发送"结束"标志代码
Sum+=ETX_end;
//changetoASCII(Sum_Check,Sum); //将“和”转化成ASCII代码
uTmp1=Sum & 0x0f;
sum_Check[1]=HexToASCII(uTmp1);//2-0x32;
uTmp1=(Sum>>4) & 0x0f;
sum_Check[0]=HexToASCII(uTmp1);//0x30;//
for(i=0;i<2;i++)
m_com.SetOutput(COleVariant((CString)sum_Check[i]));//Sum_Check));
g_bContinue=FALSE;
nTimers=0;
while(g_bContinue==FALSE)
{
ReadFromPLC();
Sleep(500);
nTimers++;
if(nTimers==5 && g_bContinue==FALSE)return;
}
if(m_data[0]==ACK_reply)//read_BUFFER==ACK_reply)
{
AfxMessageBox("ON 操作 OK!");
}
else
{
AfxMessageBox("ON 操作失败!");
}
}
void CSL_PLCView::ForceOffOperation(char *OFF_Address)
{
int i;
char sum_Check[2];
int Sum=0,uTmp1;
InitComm(1);
m_com.SetOutput(COleVariant((CString)ENQ_request));//向PLC发送ENQ请求
g_bContinue=FALSE;
int nTimers=0;
while(g_bContinue==FALSE)
{
ReadFromPLC();
Sleep(500);
nTimers++;
if(nTimers==5 && g_bContinue==FALSE)return;
}
if(m_data[0]!=ACK_reply) return ;
m_com.SetOutput(COleVariant((CString)STX_start));
m_com.SetOutput(COleVariant((CString)CMD8_ForceOFF));
Sum+=CMD8_ForceOFF;
for(i=0;i<4;i++)
{
m_com.SetOutput(COleVariant((CString)OFF_Address[i])); //发送起始元地址的ASCII代码
Sum+=OFF_Address[i];
}
m_com.SetOutput(COleVariant((CString)ETX_end));//发送"结束"标志代码
Sum+=ETX_end;
//changetoASCII(Sum_Check,Sum); //将“和”转化成ASCII代码
uTmp1=Sum & 0x0f;
sum_Check[1]=HexToASCII(uTmp1);//2-0x32;
uTmp1=(Sum>>4) & 0x0f;
sum_Check[0]=HexToASCII(uTmp1);//0x30;/
for(i=0;i<2;i++)
m_com.SetOutput(COleVariant((CString)sum_Check[i]));//Sum_Check));
g_bContinue=FALSE;
nTimers=0;
while(g_bContinue==FALSE)
{
ReadFromPLC();
Sleep(500);
nTimers++;
if(nTimers==5 && g_bContinue==FALSE)return;
}
if(m_data[0]==ACK_reply)//read_BUFFER==ACK_reply)
{
AfxMessageBox("OFF 操作 OK!");
}
else
{
AfxMessageBox("OFF 操作失败!");
}
}
void CSL_PLCView::OnReadPlc()
{
// TODO: Add your control notification handler code here
SendForReadPLC();
}
void CSL_PLCView::OnWritePlc()
{
// TODO: Add your control notification handler code here
SendForWritePLC();
}
void CSL_PLCView::OnCloseCom()
{
// TODO: Add your control notification handler code here
if(m_bCreated==FALSE) return;
if(m_com.GetPortOpen())
{
m_com.SetPortOpen(FALSE);
}
}
void CSL_PLCView::OnOn()
{
// TODO: Add your control notification handler code here
char address[]={0x30,0x30,0x38,0x30};
ForceOnOperation(address);//X0
//
// AfxBeginThread( ThreadForceOn,this,THREAD_PRIORITY_NORMAL);
}
void CSL_PLCView::OnOff()
{
// TODO: Add your control notification handler code here
char address[]={0x30,0x30,0x38,0x30};
ForceOffOperation(address);//X0
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -