东莞图冠智能科技有限公司陈安标交流QQ:458362670PC与三菱PLC之间的RS232通讯协议一、VC与PLC的串口通讯主要操作:1、对位元件和字元件状态读操作;操作对象元件:PLC内部的X、Y、M、S、T、C、D元件命令通用格式:STXCMD0ADDLENEXTCHK意义:起始符读命令元件起始位个数停止符校验码数字代码格式:0X020X30…………0X03……0x30是读操作指令;ADD是读位元件或字元件的4位起始地址,高位先发,低位后发,以ASCII码的格式发送;LEN是一次读取位元件或字元件的个数,最多可以读取0xff个字节的元件,也是以ASCII码的形式发送;CHK是两位和校验,将CMD0,ADD,LEN,EXT三项进行和累计,将和累计的最低两位转化成ASCII,高位先发,低位后发。在发完上述命令格式代码后,就可以直接读取PLC响应返回的信息,响应信息格式:STXDATAEXTCHK意义:起始符接收的数据停止符校验码数字代码格式:0x02……0x03……DATA为我们需要读取的数据;需要注意的是:读取DATA数据时遵循低位先发,高位后发的原则,所以我们解析数据的时候需要注意高低位的转换。CHK则为DATA,EXT两项的和累计的最后两位转化为ASCII。2、位元件和字元件状态写操作;操作对象元件:PLC内部的XYMSTCU元件命令通用格式:STXCMD1ADDLENDATAEXTCHK意义:起始符读命令元件起始位个数写入的数据停止符校验码数字代码格式:0X020X31……0X03……0x031是写操作指令;DATA是待写入PLC缓冲区的数据,低位先发,高位后发,以ASCII码的形式发送;其他和读指令一样,此处不再重复;发送后返回值为06,表示写入成功;返回值为15,表示写入失败;二、IPC读取PLC内部数据时:首先将需要读取的PLC内部元件的地址找到,主要内部元件地址如下:D:m_address*2+1000H;T:m_address+00C0H;C:m_address*2+01C0H;S:m_address*3;M:m_address*2+0100H;Y:m_address+00A0H;X:m_address+0080H;(只能读不能写,输入寄存器必须由外部信号驱动)m_address元件是指最低位开始后的第N个元件的位置。数据通讯举例:例1:读D0的值D0的内部地址为1000H=31H30H30H30HLEN表示我们需要读字节的个数,0-7为一个字节,D0占两个字节,所以LEN=30H32H.计算CHK校验码=CMD0+ADD+LEN+EXT=30H+31H+30H+31H+30H+30H+32H+03H=157H所以校验码为35H37H.得到完整的数字命令格式为:02H30H31H30H30H30H30H32H03H35H37H将这段数字代码发送给PLC,返回代码:02H30H30H30H30H03H43H33H得到数据段DATA为30H,31H,30H,30H=0001B(低位先发,高位后发)=1D至此得到D0=1.完成IPC读取PLC内部数据的全部过程。IO通讯举例:例2:读取Y1的值Y1的内部地址是00A0=30H30H41H30H,表示的意思是Y7-Y0的地址,Y1只是其中的一个位。LEN因为00A0只有一个字节,所以可以去LEN=01D=30H31H;计算CHK校验码=36H35H;得到完成的数字代码为:02H30H30H30H41H30H30H31H03H36H35H;返回代码:02H30H32H03H36H35H数据段为:30H32H=02D=0010B从Y7-Y0低往高排列可以知,Y1现在是状态值为1;如果这里取LEN=2D=30H32H发送代码:02H30H30H30H41H30H30H32H03H36H36H;返回代码:02H30H32H30H30H03H43H35H数据段为:30H32H30H30H=0002B(低位先发,高位后发)=2D从Y7-Y0低往高排列可以知,Y1现在是状态值为1;注意:全部过程中,PLC内部程序不需要做任何程序编写。三、PLC读取IPC数据时:数据通讯举例:例1:PLC读取IPC内部参数X的值。思路:1、先将X的值转化成数字代码形式。2、再讲X的值发送写入PLC内部数据寄存器中;3、然后PLC直接读取这个数据寄存器的数据。设:X=2;数据写入PLC内部数据寄存器D0中则DATA=X=2=0010H=31H30H30H30H(低位先发,高位后发);ADD=31H30H30H30H;LEN=02D=30H32H.;(D为10进制;H为16进制)CHK=CMD1+ADD+LEN+DATA+EXT;=31H+31H+30H+30H+30H+30H+32H+31H+30H+30H+30H+03H=218H则校验码为:31H38H完整的数字代码为:02H31H31H30H30H30H30H32H31H30H30H30H03H31H38H返回值为06表示写入成功,PLC直接读取D0里面的数据即可。完成PLC读取IPC数据。当然这只是即时的读取,如果需要可控性的话,需要增加自定义读取和发送标志位,多加个数据用来表示控制字节用。IO通讯举例:例2:IPC置位PLC内部位元件Y1思路:1、确定Y1地址(读操作已说明);2、就于写入的原理,需要先读取00A0的值;3、将读取的值与0010进行&运算,确定Y1是否为0;4、为0,则将读取值与0010进行或运算,再将得到的值转为数字代码形式发送给PLC;为1,则表示内部Y1已经为1,不需要重复置位;5、写入成功后返回06;编写VC程序时需要用到以上思路;这里我们假设我们只是写入Y1=1来操作:Y1的PLC内部地址为:00A0H;表示Y7-Y0的地址,Y1只是其中一个位;LEN取2个字节16位=30H32H;写入数据:00A0表示的是Y7-Y08个位,需要Y1为1,写入00000010B=02H,但是LEN为2,表示2个字节,所以需要写入0002H转化为30H32H30H30H(低位先发,高位后发);完整代码:02H31H30H30H41H30H30H32H30H32H30H30H03H32H39H返回:06写入成功。四、数据通讯VC代码编写分析实例:例1:将IPC端3个数据:X=1003.5;Y=-4500;Z=-3.1456写入PLC中代码编写步骤:1、将XYZ分别转化成整数,然后保存其小数位数,这里将XYZ分别都乘以10的N次方,直到其不在-32767-32767范围后分别保存乘以10的个数在N1,N2,N3中;从而得到X=10035;N1=1;Y=-4500;N2=0;Z=31456;N3=4;2、将X、Y、Z、N1、N2、N3分别转换成16进制;3、再转化为16进制ASCII码;4、将得到的16进制ASCII码按照X、N1、Y、N2、Z、N3的顺序排列进counts[35]数组中;5、计算校验码;6、将数据counts[35]每个数转化为对应的两个ASCII码值保存于counts_ascii[70]中;例如:“35”转化为“3”和“5”;7、将ASCII码转化为字符串代码保存于a2[70],累加排列输出;例如:“3”的字符串代码为48+3=51;8、返回值06,表示写入成功。例2:读取PLC内部数据X、Y、Z的值(读取D0-D5的数据)代码编写步骤:(思路与上例一样)1、将固定读取的数字代码发送给PLC,固定读取D0-D5的数字代码为:02H30H31H30H30H30H30H43H03H36H37H2、发送成功后,则有数据信息反馈;不成功则返回15;3、将返回的窗口输出字符串依次保存在字符串数组chars1[84]中;4、将数组s1转化为数字保存在数据b中;类似:字符串数字51=“3”;5、将数组b转为16进制ASCII,再转化为10进制保存在数组c中;例如:“3”“5”=3*10+5=35;再如:35H=5D;6、将数组c转为2进制,方便判断正负数和后期运算,保存在数值c2中;7、判断正负数,设立标志位flog;如果为负数,则将其二进制取反加1后转化为10进制整数;如果不为负数,则直接转化为10进制整数;8、得到的数分别保存在D0、D1、D2、D3、D4、D5中(IPC内部变量区别开PLC内部数据寄存器);自定义运算;可以得到X=D0/(10^D1);//D0除以10的D1次方Y=D2/(10^D3);Z=D4/(10^D5);