工控编程吧
标题:
326上位机VC MFC控制永宏PLC启动停止
[打印本页]
作者:
qq263946146
时间:
2016-9-22 14:19
标题:
326上位机VC MFC控制永宏PLC启动停止
(, 下载次数: 5)
上传
点击文件名下载附件
控制永宏PLC启动停止
功能展示
PLC在我们工业控件领域非常常见,品牌也多,那么如何通过上位机程序控制PLC呢?我们当前例程实现编写代码通过串口控制永宏PLC启动及停止,效果如图,首先打开串口及设置串口,然后就可以通过两按钮启动与停止永宏PLC的操作;
要点提示
永宏PLC的通讯帧格式可以翻阅其通讯手册,帧是基于ASCII格式,通讯过程中主要是校验码如何计算,不同品牌PLC的校验码计算方式不同,常见有校验方法有CRC校验,LRC校验(纵向冗余校验Longitudinal Redundancy Check,简称:LRC)永宏PLC采用LRC校验,即从头至尾依序相加,不考虑进位;
实现功能
1.新建基于对话框的应用程序
2. 依次添加按钮控件<打开串口><设置串口><启动永宏PLC><停止永宏PLC>关联按钮的点击函数
void CGkbc8Dlg::OnButton1() //打开串口
{
m_hCom = CreateFile("COM4", //打开串口1
GENERIC_READ|GENERIC_WRITE, //允许读和写操作
0, //独占方式
NULL,
OPEN_EXISTING, //打开一个存在的串口
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, //异步方式打开
NULL
);
if (m_hCom==INVALID_HANDLE_VALUE)
MessageBox("端口打开失败");
else
MessageBox("端口打开成功");
}
void CGkbc8Dlg::OnButton2()
{
SetupComm(m_hCom,1024,1024); //设置发送和接收缓冲区大小
DCB dcb;
GetCommState(m_hCom,&dcb); //获得串口默认信息
dcb.BaudRate = 9600;
dcb.fBinary = TRUE;
dcb.fParity = TRUE;
dcb.ByteSize = 8;
dcb.Parity = ODDPARITY;
dcb.StopBits = ONESTOPBIT;
if (!SetCommState(m_hCom,&dcb))//设置串口信息
{
MessageBox("串口参数设置失败","提示");
return;
}
void CGkbc8Dlg::OnButton3() //永宏PLC启动
{
CString sBuffer="";
sBuffer += 0x02; //起始字符(固定)
sBuffer += 0X30; //PLC站号
sBuffer += 0X31;
sBuffer += 0x34; //PLC启停命令码(固定)
sBuffer += 0x31;
sBuffer += 0x31; //PLC启动 (固定)
sBuffer += PLCCalFrameCheck(sBuffer);//校验码
sBuffer += 0X03; //结束字符(固定)
//<>
unsigned long res;
DWORD factdata = 0;
wOverLaped.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
IsStop = FALSE;
//开始发送数据
if (WriteFile(m_hCom,sBuffer,sBuffer.GetLength(),&factdata,&wOverLaped))
{
IsStop = TRUE;
MessageBox("发送成功");
}
else
{
res = WaitForSingleObject(wOverLaped.hEvent,5000); //延时5秒,等待数据发送
if (WAIT_OBJECT_0 == res) //如果事件处于有信号状态,表示发送完成
{
IsStop = TRUE;
}
else
IsStop = FALSE;
Sleep(1000); //延时1秒钟
}
}
3.在主对话框源文件顶部添加变量及线程函数
OVERLAPPED tOverLaped= {0}; //线程函数使用的OVERLAPPED结构
OVERLAPPED wOverLaped = {0}; //写操作使用的 OVERLAPPED结构
OVERLAPPED rOverLaped = {0}; //读操作使用的 OVERLAPPED结构
BOOL IsWaitExit = FALSE; //安全退出线程用
BOOL IsStop = FALSE; //数据是否发送完毕
DWORD ThreadFunction(LPVOID pParam) //线程函数
{
DWORD dwEvtMask ,dwResult;
tOverLaped.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);//创建一个事件
while (!IsWaitExit)
{
WaitCommEvent(((CGkbc8Dlg*)AfxGetMainWnd())->m_hCom,&dwEvtMask,&tOverLaped);//等待窗口事件
dwResult = WaitForSingleObject(tOverLaped.hEvent,100); //如果事件没有信号,延时0.1秒
switch (dwResult)
{
case WAIT_OBJECT_0: //事件对象有信号
switch (dwEvtMask)
{
case EV_RXCHAR: //接收到数据
{
if (IsStop)//发送停止
{
IsStop = FALSE;
//发送消息,由消息处理函数接收数据
:
ostMessage(AfxGetMainWnd()->m_hWnd, CM_RECEIVE,0,(LPARAM)EV_RXCHAR);
}
break;
}
}
break;
}
}
return 0;
}
4 。自定义一用户消息#define CM_RECEIVE WM_USER+1//自定义一个消息,且手动添加映射此消息的处理函数OnRecieveData(),具体的操作可以看接下来的视频演示,最后是给主对话框添加一串口的句柄变量public:
HANDLE m_hCom; //串口句柄 ,用于对串口的设置,发送数据等操作。
我们还自定义有两个函数 CString itoa_2H(UINT nSource); //convert int to 2bit ASCII in hex
CString PLCCalFrameCheck(CString sFrame); //发送命令时,计算PLC校验码
可以打开例程源码查看
我们来演示下功能实现的整个过程
[iqiyi]http://player.video.qiyi.com/dc1192267d6b84ad19c6840f9533a32d/0/0/w_19rstj0l9h.swf-albumId=6347953609-tvId=6347953609-isPurchase=0-cnId=12[/iqiyi]
(, 下载次数: 0)
上传
点击文件名下载附件 [weixinlianxi]1[/weixinlianxi]
[note]1[/note]
欢迎光临 工控编程吧 (https://www.gkbc8.com/)
Powered by Discuz! X3.4