三菱plc编程口的通讯协议比较简单,只有四个命令,即:
命令 命令码 目标设备
device read cmd 0 x,y,m,s,t,c,d
device write cmd 1 x,y,m,s,t,c,d
force on cmd 7 x,y,m,s,t,c
force off cmd 8 x,y,m,s,t,c五个标示:
enq 05h 请求
ack 06h plc正确响应
nak 15h plc错误响应
stx 02h 报文开始
etx 03h 报文结束
使用累加方式的和校验,帧格式如下:
stx cmd data ...... data etx sum(upper) sum(lower)
和校验:
sum= cmd+„„+etx。 如sum=73h,sum=“73”。
1、device read(读出软设备状态值)
计算机向plc发送:
始命令 首地址 位数 终和校验
stx cmd group address bytes etx sum plc 返回
stx 1st data 2nd data ..... last data etx sum
2、device write(向plc 软设备写入值)
计算机向plc发送:
始命令 首地址 位数 数据 终和校验
plc 返回
ack (06h) 接受正确
nak (15h) 接受错误
3、位设备强制置位/复位
force on 置位
始命令 地址 终和校验
stx cmd address etx sum 02h 37h address 03h sum force off 复位
始 命令 地址 终 和校验 stx cmd address etx sum 02h 38h address 03h sum plc 返回
ack(06h) 接受正确
nak(15h) 接受错误
以上可以看出,协议非常简单,但是由于没有寄存器类型信息,所以地址的计算十分关键,如d100和m100分别对应哪个地址呢?下面就是三菱fx系列plc地址对应表:
public const plc_d_base_address = 4096 =1000h
public const plc_d_special_base_address = 3584 =e00h
public const plc_y_group_base_address = 160 =a0h
public const plc_py_group_base_address = 672 =2a0h
public const plc_t_group_base_address = 192 =c0h
public const plc_ot_group_base_address = 704 =2c0h
public const plc_rt_group_base_address = 1216 =4c0h
public const plc_m_single_base_address = 2048(命令为7或8时) =800h
public const plc_m_group_base_address = 256 =100h
public const plc_pm_group_base_address = 768 =300h
public const plc_s_group_base_address = 0 =0h
public const plc_x_group_base_address = 128 =80h
public const plc_c_group_base_address = 448 =1c0h
public const plc_oc_group_base_address = 960 =3c0h
public const plc_rc_group_base_address = 1472 =5c0h
public const plc_tv_group_base_address = 2048 =800h
public const plc_cv16_group_base_address = 2560 =a00h
public const plc_cv32_group_base_address = 3072 =c00h
当我们用device read命令时,d100地址=100*2+4096;m100地址=100+256;不同的是d类型寄存器存放的是字,m寄存器存放的是位,同样是读两个字节,d100返回的就是plc中d100地址的值,m类型寄存器返回的是m100到m116的值。所以当我们用force on 命令时,m100寄存器地址=100+2048;
这也没有什么复杂的,不是吗?可是三菱公司好像不甘于如此,force on/off命令中地址排列与device read/write不同,是低位在前高位在后。如y20,地址是0510h,代码中4个字节地址表示为:1005。(注意:y寄存器为八进制,如y20地址=16+1280=0510h) 其实一点技术含量都没有,就是拐了几个弯,偏偏很多时候又不都告诉你,让人浪费不少时间。不废话了,自己做个程序试试吧。