1 引言
可编程控制器是一种数字运算操作的电子系统,专为在工业环境下应用而设计。它采用了可编程序的存储器,用于其内部存储程序,执行逻辑运算、顺序控制、定时、计数和算术操作等面向用户的指令,并通过数字式或模拟式输入输出控制各种类型的机械的生产过程。可编程控制器及其有关外部设备,都按易于与工业控制系统联成一个整体、易于扩充其功能的原则设计。早期的plc以数字量的顺序控制为主,提供了简单的慢速的通信功能(只支持rs232、rs485、多采用modbus协议),现在的plc不仅具有逻辑运算、顺序控制、定时、计数和算术操作,而且还具有a/d、d/a转换,数值计算和数据处理等功能。它既可以对开关量进行控制,也可以对模拟量进行控制,随着plc功能不断扩充,它还有通讯联网功能。本文就是基于松下电工的专门通信协议(mewtocol),用vc++开发的上位机与plc间的通信。
2 松下电工的专用通信协议mewtocol-com
目前,随着plc的快速发展,越来越多的plc生产厂商开发了它与计算机的通信功能(主要是利用计算机串口进行通信),本文是以松下fp系列plc为例,作详细阐述。在一台计算机于plc之间的通信中,通信由计算机发动,把命令帧发向plc,plc将以响应帧作应答,并执行相应的动作。
(1) 命令帧格式
其中: %:mewtocol-com的命令帧开始标志(ascii码为25h)。
h,l:站地址的高位和低位。
#:站号特征码(ascii码为23h)。
发送文本:由命令码和数据组成,其主要命令码如表1所示。
bcc:校验码,采用异或校验码,bcc为8位。
(2) 响应帧格式
当主站发来命令帧之后,从站将以响应帧作应答。响应帧分为2种,若主站命令帧正确无误,则用“正确响应帧”作应答;如果主站命令帧有错误则用“错误响应帧”作应答。这两种应帧格式下。正确响应帧的格式
其中 %,h,l,bcc,cr含义与命令帧相同。
$:正确响应的标志(acsii码为24h)。
响应文本:应当按照命令帧要求及协议规定组织。
错误响应帧的格式
其中%,h,l,bcc,cr含义与命令帧相同。
!:错误响应帧的标志(acsii码为21h)。
错误代码:对于命令及数据传送中的各种错误均规定为代码以识别。
(3) 命令码: mewtocol-com协议的命令码汇总如表1所示
(4)常用的命令与格式
a)单接点的读
错误响应帧与单接点的相同。
3 用visual c++6.0编写串行通信程序
(1) mscomm控件
串行通讯编程基本过程:设置初始化并打开串行口—配置串口—双向传输数据—校验—释放串口。本文的上位机通信程序是用visualc++6.0编写的,主要是利用vc++中的一个通信控件mscomm来现的。
该控件屏蔽了通讯过程中的底层操作,程序员应用时只需设置,监控mscomm控件的属性和事件即可完成对串口的初始化和数据的输入输出工作。mscomm控件的主要属性如下:
* commport:设置并返回通讯端口号,设计时端口号可设为1到16的任何数(默认值为1)。如:setcommport(1);即设置当前通讯端口为com1。
* settings:设置并返回波特率,奇偶校验,数据位长度,停止位长度。
如:setsettings(lpctstr string);string是一个包括四部分的字符串:第一部分:波特率;
第二部分:奇偶校验,n表示不校验,e表示偶校验,o表示奇校验,s表示空格校验,m表示符号校验;
第三部分:数据为长度,其可选值为4,5,6,7,8;
第四部分:停止位长度,其可选为1,1.5,2。 settings属性的缺省值为“9600,n,8,1”。
* portopen:用于打开和关闭端口。setportopen(bool bnewvalue);
当bnewvalue为true时打开端口,当为false时关闭端口。
* input:从接受缓冲区返回和删除字符,该属性在运行时为只读。getinput();
* output:向缓冲区写数据,要传送的数据可以是文本数据或是二进制数据。
*commevent:返回最近的通讯事件或错误。只要有通讯错误或事件发生时都会产生oncomm事件,commevent属性中存有错误或事件的数值代码。
getcommevent();
4 程序框架的生成及控件属性的配置
首先利用mfcappwizard(exe)建立一个基于对话框,支持activex控件,命名为transcomn的应用程序。然后在对话框中加入一些控件,其中那个mscomm控件(电话形状的控件)必须是在系统中注册过的microsoft communications control,由它进行通讯时首先得设置它的一些属性,这些属性既可以在控件属性对话框中设置也可以在程序中设置,本文用后一种方法,在程序中对mscomm控件属性设置。最后用classwizard为控件添加变量和响应函数如表2
5 程序编写
// transcommdlg.cpp : implementation file
bool ctranscommdlg::oninitdialog()
{
//初始化通讯端口,波特率为9600,奇校验,8位数据位,1位校验位,选择com1口
cdialog::oninitdialog();
m_comm.setcommport(1);
m_comm.setsettings(“9600,o,8,1”);
m_comm.setinputmode(1);
m_comm.setportopen(true);
return true; // return true unless you set the focus to a
control
}
void ctranscommdlg::onsend()
{
updatedata(true);
variant vresponse;
char *str;
//把对话框中有用户输入的命令字符串cstring
//m_commandstring,由串口发出
m_comm.setoutput(colevariant(m_commandstring));
sleep(50);//延时50毫秒,一个保证有足够的时间 //让plc响应命令
//读取串口输入缓冲区中的字符个数,如大于0表 //示串口接受到plc的响应帧,然后//进行处理
int k=m_comm.getinbuffercount();
if(k》0)
{
//把plc发送来的响应帧转换为字符 //串,并在对话框的响应文本框中显示
vresponse=m_comm.getinput();
str=(char *)(unsigned char*)vresponse.parray-》pvdata;
str[k]='';
}
}
转载请注明出处。