三菱PLC 内部寄存器 通信 地址计算 算法

您所在的位置:网站首页 三菱变频器与触摸屏通讯地址表 三菱PLC 内部寄存器 通信 地址计算 算法

三菱PLC 内部寄存器 通信 地址计算 算法

2023-07-30 13:22| 来源: 网络整理| 查看: 265

    首先将需要读取的PLC内部元件的地址找到,主要内部元件地址如下:

    D:   PLC-Address*2+1000H;

    T:   PLC-Address+00C0H;

    C:   PLC-Address*2+01C0H;

    S:   PLC-Address*3;

    M:   PLC-Address*2+0100H;

    Y:   PLC-Address+00A0H;

    X:   PLC-Address+0080H;(只能读不能写,输入寄存器必须由外部信号驱动)

         PLC-Address元件是指最低位开始后的第N个元件的位置。

 

一、VC与PLC的串口通讯主要操作: 1、对位元件和字元件状态读操作; 操作对象元件:PLC内部的X、Y、M、S、T、C、D元件 命令通用格式: STX CMD0 ADD LEN EXT CHK 意义: 起始符 读命令 元件起始位 个数 停止符 校验码 数字代码格式: 0X02 0X30 …… …… 0X03 …… 0x30是读操作指令; ADD是读位元件或字元件的4位起始地址,高位先发,低位后发,以ASCII码的格式发送; LEN是一次读取位元件或字元件的个数,最多可以读取0xff个字节的元件,也是以ASCII码的形式发送; CHK是两位和校验,将CMD0,ADD,LEN,EXT三项进行和累计,将和累计的最低两位转化成ASCII,高位先发,低位后发。 在发完上述命令格式代码后,就可以直接读取PLC响应返回的信息, 响应信息格式:STX DATA EXT CHK 意义: 起始符 接收的数据 停止符 校验码 数字代码格式:0x02 …… 0x03 …… DATA为我们需要读取的数据; 需要注意的是:读取DATA数据时遵循低位先发,高位后发的原则,所以我们解析数据的时候需要注意高低位的转换。 CHK则为DATA,EXT两项的和累计的最后两位转化为ASCII。 2、位元件和字元件状态写操作; 操作对象元件:PLC内部的XYMSTCU元件 命令通用格式:STX CMD1 ADD LEN DATA EXT CHK 意义: 起始符 读命令 元件起始位 个数 写入的数据 停止符 校验码 数字代码格式:0X02 0X31 …… 0X03 …… 0x031是写操作指令; DATA是待写入PLC缓冲区的数据,低位先发,高位后发,以ASCII码的形式发送; 其他和读指令一样,此处不再重复; 发送后返回值为06,表示写入成功; 返回值为15,表示写入失败; 数据通讯举例: 例1:读D0的值 D0的内部地址为1000H=31H 30H 30H 30H LEN表示我们需要读字节的个数,0-7为一个字节,D0占两个字节,所以LEN=30H 32H. 计算CHK校验码=CMD0+ADD+LEN+EXT =30H+31H+30H+31H+30H+30H+32H+03H=157H 所以校验码为35H 37H. 得到完整的数字命令格式为:02H 30H 31H 30H 30H 30H 30H 32H 03H 35H 37H 将这段数字代码发送给PLC, 返回代码:02H 30H 30H 30H 30H 03H 43H 33H 得到数据段DATA为30H,31H,30H,30H=0001B(低位先发,高位后发)=1D 至此得到D0=1. 完成IPC读取PLC内部数据的全部过程。 IO通讯举例: 例2:读取Y1的值 Y1的内部地址是00A0=30H 30H 41H 30H,表示的意思是Y7-Y0的地址,Y1只是其中的一个位。 LEN因为00A0只有一个字节,所以可以去LEN=01D=30H 31H; 计算CHK校验码=36H 35H; 得到完成的数字代码为:02H 30H 30H 30H 41H 30H 30H 31H 03H 36H 35H; 返回代码:02H 30H 32H 03H 36H 35H 数据段为:30H 32H=02D=0010B 从Y7-Y0低往高排列可以知,Y1现在是状态值为1; 如果这里取LEN=2D=30H 32H 发送代码:02H 30H 30H 30H 41H 30H 30H 32H 03H 36H 36H; 返回代码:02H 30H 32H 30H 30H 03H 43H 35H 数据段为:30H 32H 30H 30H=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=31H 30H 30H 30H(低位先发,高位后发); ADD=31H 30H 30H 30H; LEN=02D=30H 32H.;(D为10进制;H为16进制) CHK=CMD1+ADD+LEN+DATA+EXT;    =31H+31H+30H+30H+30H+30H+32H+31H+30H+30H+30H+03H=218H   则校验码为:31H 38H 完整的数字代码为:02H 31H 31H 30H 30H 30H 30H 32H 31H 30H 30H 30H 03H 31H 38H 返回值为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位=30H 32H; 写入数据:00A0表示的是Y7-Y0 8个位,需要Y1为1,写入00000010B=02H,但是LEN为2,表示2个字节,所以需要写入0002H转化为30H 32H 30H 30H(低位先发,高位后发); 完整代码:02H 31H 30H 30H 41H 30H 30H 32H 30H 32H 30H 30H 03H 32H 39H 返回: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的数字代码为:02H 30H 31H 30H 30H 30H 30H 43H 03H 36H 37H 2、发送成功后,则有数据信息反馈;不成功则返回15; 3、将返回的窗口输出字符串依次保存在字符串数组char s1[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);

 

'Private Declare Sub Sleep Lib "kernel32" (ByVal dwseconds As Long) '延时函数毫秒 Dim ik As Integer Dim str_write() As Byte '发送数组 Dim str_val(0 To 5) As Byte Dim 非读操作 As Boolean '此位为真是表示有非读命令等待执行,那么暂停读命令,执行非读操作 Dim 何种非读操作 As Integer '此变量用来区分等待的是何种非读命令 Dim 读操作 As Boolean '此变量作用:当有非读命令而读操作的接收处理没有完成时,先完成读命令的接收处理 Dim i As Integer '此变量作用:读操作时因为读的类型不一样,所以每次读一种(如X),然后下一次根据i的数值判断是应该读那种类型。 Dim 第一次 As Boolean Dim dz As Integer '元件操作地址 Dim lie As Byte, lie1 As Byte, lie2 As Byte '元件操作类型 Dim SRet As Byte Private Sub Command1_Click(Index As Integer) '写VW0---VW30 Dim shuju As String Dim shuju1 As String Dim shuju2 As String ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 非读操作 = True 何种非读操作 = 3 shuju = Right("0000" + Hex(Text4(Index).Text), 4) shuju1 = ("&H" & Mid(shuju, 1, 2)) shuju2 = ("&H" & Mid(shuju, 3, 2)) ReDim str_write(0 To 38) As Byte '重新定义数组 str_write(0) = &H68 str_write(1) = &H21 str_write(2) = &H21 str_write(3) = &H68 str_write(4) = &H2 str_write(5) = &H0 str_write(6) = &H6C str_write(7) = &H32 str_write(8) = &H1 str_write(9) = &H0 str_write(10) = &H0 str_write(11) = &H0 str_write(12) = &H0 str_write(13) = &H0 str_write(14) = &HE str_write(15) = &H0 str_write(16) = &H6 str_write(17) = &H5 '写 str_write(18) = &H1 str_write(19) = &H12 str_write(20) = &HA str_write(21) = &H10 str_write(22) = &H2 str_write(23) = &H0 str_write(24) = &H2 str_write(25) = &H0 str_write(26) = &H1 str_write(27) = &H84 str_write(28) = &H0 str_write(29) = &H0 str_write(30) = (Index * 2 * 8) Mod 256 str_write(31) = &H0 str_write(32) = &H4 str_write(33) = &H0 str_write(34) = &H10 str_write(35) = shuju1 str_write(36) = shuju2 str_write(37) = SumChk(str_write) str_write(38) = &H16 End Sub ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Private Sub Command2_Click(Index As Integer) 'S元件状态操作 非读操作 = True 何种非读操作 = 0 dz = Index lie = &H4 lie1 = &H0 lie2 = &H7C If Command2(Index).Caption = "S0." + Trim(Index) + "复位" Then SRet = &H0 Else SRet = &H1 End If End Sub ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Private Sub Command3_Click(Index As Integer) 'M元件状态操作 非读操作 = True 何种非读操作 = 0 dz = Index lie = &H83 lie1 = &H0 lie2 = &H7C If Command3(Index).Caption = "M0." + Trim(Index) + "复位" Then SRet = &H0 Else SRet = &H1 End If End Sub ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Private Sub Command4_Click(Index As Integer) 'V元件状态操作 非读操作 = True 何种非读操作 = 0 dz = Index lie = &H84 lie1 = &H1 lie2 = &H6C If Command4(Index).Caption = "V0." + Trim(Index) + "复位" Then SRet = &H0 Else SRet = &H1 End If End Sub Private Sub Command5_Click() '启动 非读操作 = True 何种非读操作 = 1 ReDim str_write(0 To 38) As Byte '重新定义数组 str_write(0) = &H68 str_write(1) = &H21 str_write(2) = &H21 str_write(3) = &H68 str_write(4) = &H2 str_write(5) = &H0 str_write(6) = &H7C str_write(7) = &H32 str_write(8) = &H1 str_write(9) = &H0 str_write(10) = &H0 str_write(11) = &H0 str_write(12) = &H0 str_write(13) = &H0 str_write(14) = &H14 str_write(15) = &H0 str_write(16) = &H0 str_write(17) = &H28 str_write(18) = &H0 str_write(19) = &H0 str_write(20) = &H0 str_write(21) = &H0 str_write(22) = &H0 str_write(23) = &H0 str_write(24) = &HFD str_write(25) = &H0 str_write(26) = &H0 str_write(27) = &H9 str_write(28) = &H50 str_write(29) = &H5F str_write(30) = &H50 str_write(31) = &H52 str_write(32) = &H4F str_write(33) = &H47 str_write(34) = &H52 str_write(35) = &H41 str_write(36) = &H4D str_write(37) = SumChk(str_write) str_write(38) = &H16 End Sub ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Private Sub Command6_Click() '停止 ReDim str_write(0 To 34) As Byte '重新定义数组 非读操作 = True 何种非读操作 = 2 str_write(0) = &H68 str_write(1) = &H1D str_write(2) = &H1D str_write(3) = &H68 str_write(4) = &H2 str_write(5) = &H0 str_write(6) = &H7C str_write(7) = &H32 str_write(8) = &H1 str_write(9) = &H0 str_write(10) = &H0 str_write(11) = &H0 str_write(12) = &H0 str_write(13) = &H0 str_write(14) = &H10 str_write(15) = &H0 str_write(16) = &H0 str_write(17) = &H29 str_write(18) = &H0 str_write(19) = &H0 str_write(20) = &H0 str_write(21) = &H0 str_write(22) = &H0 str_write(23) = &H9 str_write(24) = &H50 str_write(25) = &H5F str_write(26) = &H50 str_write(27) = &H52 str_write(28) = &H4F str_write(29) = &H47 str_write(30) = &H52 str_write(31) = &H41 str_write(32) = &H4D str_write(33) = SumChk(str_write) str_write(34) = &H16 End Sub ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Private Sub Combo1_Click() '通讯口选择 Call CommSet '调用通讯口设置过程 End Sub ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Private Sub CommSet() On Error GoTo err1 '此处作用:如果您选择了电脑中不存在的通讯口,则提示“无效的通讯口” If MSComm1.PortOpen = True Then MSComm1.PortOpen = False MSComm1.CommPort = Val(Mid(Combo1.Text, 4, 1)) MSComm1.Settings = "9600,e,8,1" MSComm1.InBufferCount = 0 MSComm1.OutBufferCount = 0 MSComm1.InputLen = 0 MSComm1.RThreshold = 0 MSComm1.InputMode = comInputModeBinary MSComm1.PortOpen = True 第一次 = False 非读操作 = False str_val(0) = &H10 str_val(1) = &H2 str_val(2) = &H0 str_val(3) = &H5C str_val(4) = &H5E str_val(5) = &H16 Timer1.Enabled = True Exit Sub ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ err1: MsgBox Err.Description '错误提示 End Sub ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Private Sub Form_Load() Dim g As Integer On Error GoTo err1 '此处作用:如果您选择了电脑中不存在的通讯口,则提示“无效的通讯口” For g = 1 To 9 '添加通讯选择 Combo1.AddItem "Com" & Trim$(Str$(g)) Next g MSComm1.CommPort = 1 MSComm1.Settings = "9600,e,8,1" MSComm1.InBufferCount = 0 MSComm1.OutBufferCount = 0 MSComm1.InputLen = 0 MSComm1.RThreshold = 0 MSComm1.InputMode = comInputModeBinary MSComm1.PortOpen = True 第一次 = False 非读操作 = False str_val(0) = &H10 str_val(1) = &H2 str_val(2) = &H0 str_val(3) = &H5C str_val(4) = &H5E str_val(5) = &H16 Timer1.Enabled = True Exit Sub ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ err1: MsgBox Err.Description '错误提示 End Sub ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Private Sub Form_Unload(Cancel As Integer) MSComm1.InBufferCount = 0 MSComm1.OutBufferCount = 0 If MSComm1.PortOpen = True Then MSComm1.PortOpen = False End End Sub Private Function SumChk(Dats) As Byte '校验和计算 Dim l As Integer, j As Integer Dim Temp_FCS As Variant l = UBound(Dats) For j = 4 To l 'Len 函数,返回 Long,其中包含字符串内字符的数目,或是存储一变量所需的字节数 Temp_FCS = Temp_FCS + str_write(j) Next j SumChk = Temp_FCS Mod 256 End Function Private Function dec2bin(Dats$) As String '转换成二进制 Dim bin8 Dim bin4 Dim bin2 Dim bin1 Dim bin16 Dim bin32 Dim bin64 Dim bin128 If Dats \ 128 >= 1 Then bin128 = 1 Else bin128 = 0 End If If (Dats Mod 128) \ 64 >= 1 Then bin64 = 1 Else bin64 = 0 End If If (Dats Mod 64) \ 32 >= 1 Then 'Mod用来对两个数作除法并且只返回余数 bin32 = 1 Else bin32 = 0 End If If (Dats Mod 32) \ 16 >= 1 Then bin16 = 1 Else bin16 = 0 End If If (Dats Mod 16) \ 8 >= 1 Then '\ 运算符用来对两个数作除法并返回一个整数 bin8 = 1 Else bin8 = 0 End If If (Dats Mod 8) \ 4 >= 1 Then 'Mod用来对两个数作除法并且只返回余数 bin4 = 1 Else bin4 = 0 End If If (Dats Mod 4) \ 2 >= 1 Then bin2 = 1 Else bin2 = 0 End If If Dats Mod 2 = 0 Then bin1 = 0 Else bin1 = 1 End If bin128 = CStr(bin128) 'CStr 函数将一数值转换为 String bin64 = CStr(bin64) bin32 = CStr(bin32) bin16 = CStr(bin16) bin8 = CStr(bin8) 'CStr 函数将一数值转换为 String bin4 = CStr(bin4) bin2 = CStr(bin2) bin1 = CStr(bin1) dec2bin = bin128 + bin64 + bin32 + bin16 + bin8 + bin4 + bin2 + bin1 End Function ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Private Sub MSComm1_OnComm() Dim rcv_array() As Byte Dim rcv_len As Long Dim read As String, read1 As String Dim j As Integer Dim wei(2) As String If MSComm1.CommEvent = comEvReceive Then 'CommEvent的属性返回的值为comEvReceive时是发生了接收事件. rcv_array = MSComm1.Input If 第一次 = True Then '判断发送的是那一组 If Right("00" + Hex(rcv_array(0)), 2) "E5" Then '如果返回的不是E5,则重新发数据 Shape6.BackColor = &HC0& MSComm1.RThreshold = 0 Timer1.Enabled = True Timer2.Enabled = False Text5 = "1" Else '如果是E5,则发最后一组数据 If 非读操作 = True And 读操作 = False Then '如果是非读命令产生的接收事件 Select Case 何种非读操作 Case 0 '置/复位 MSComm1.RThreshold = 24 Case 1 'PLC启动 MSComm1.RThreshold = 20 Case 2 'PLC停止 MSComm1.RThreshold = 20 Case 3 '数值写入 MSComm1.RThreshold = 18 End Select Else '如果是实时监控 Select Case i Case 0 '读M0.0—M0.7 MSComm1.RThreshold = 28 Case 1 '读T0 MSComm1.RThreshold = 30 Case 2 '读V0.0—V0.7 MSComm1.RThreshold = 28 Case 3 '读输入 MSComm1.RThreshold = 29 Case 4 '读VW0—VW15 MSComm1.RThreshold = 59 Case 5 '读输出 MSComm1.RThreshold = 29 Case 6 '读S0.0—S0.7 MSComm1.RThreshold = 28 Case 7 '读C0 MSComm1.RThreshold = 30 End Select End If '判断非读操作结束 MSComm1.InBufferCount = 0 MSComm1.OutBufferCount = 0 MSComm1.Output = str_val '发送命令 第一次 = False Text5 = "2" End If '判断返回的E5是否正确结束 Else '如果是第二组命令 rcv_len = UBound(rcv_array) '返回一个 Long 型数据,其值为指定的数维组可用的最大下标 For j = 0 To rcv_len read = read & Right("00" + Hex(rcv_array(j)), 2) Next j If 非读操作 = True And 读操作 = False Then '如果是非读命令产生的接收事件 非读操作 = False ' Shape6.BackColor = &HC0& MSComm1.InBufferCount = 0 MSComm1.OutBufferCount = 0 Timer1.Enabled = True Else '如果是实时监控命令产生的接收事件 Select Case i Case 0 '读M0.0—M0.7 read1 = Val("&H" + Mid(Right(read, 6), 1, 2)) wei(0) = dec2bin(read1) '调用十二进转二进制过程 For j = 0 To 7 If Mid(wei(0), 8 - j, 1) = "1" Then Shape4(j).BackColor = &HC0& Command3(j).Caption = "M0." + Trim(j) + "复位" Else Shape4(j).BackColor = &HE0E0E0 Command3(j).Caption = "M0." + Trim(j) + "置位" End If Next j Case 1 '读T0 read1 = Val("&H" + Mid(Right(read, 8), 1, 4)) Text2.Text = read1 'T当前值显示 Case 2 '读V0.0—V0.7 read1 = Val("&H" + Mid(Right(read, 6), 1, 2)) wei(0) = dec2bin(read1) '调用十二进转二进制过程 For j = 0 To 7 If Mid(wei(0), 8 - j, 1) = "1" Then Shape5(j).BackColor = &HC0& Command4(j).Caption = "V0." + Trim(j) + "复位" Else Shape5(j).BackColor = &HE0E0E0 Command4(j).Caption = "V0." + Trim(j) + "置位" End If Next j Case 3 '读输入 read1 = Mid(Right(read, 8), 1, 4) wei(0) = dec2bin(Val("&H" + Mid(read1, 1, 2))) '调用十二进转二进制过程 wei(1) = dec2bin(Val("&H" + Right(read1, 2))) '调用十二进转二进制过程 wei(2) = wei(1) + wei(0) For j = 0 To 15 If Mid(wei(2), 16 - j, 1) = "1" Then Shape1(j).BackColor = &HC0& Else Shape1(j).BackColor = &HE0E0E0 End If Next j Case 4 '读VW0—VW15 read1 = Mid(Right(read, 68), 1, 64) For j = 0 To 15 Text1(j).Text = Val("&H" + Mid(read1, 1 + j * 4, 4)) Next j Case 5 '读输出 read1 = Mid(Right(read, 8), 1, 4) wei(0) = dec2bin(Val("&H" + Mid(read1, 1, 2))) '调用十二进转二进制过程 wei(1) = dec2bin(Val("&H" + Right(read1, 2))) '调用十二进转二进制过程 wei(2) = wei(1) + wei(0) For j = 0 To 15 If Mid(wei(2), 16 - j, 1) = "1" Then Shape2(j).BackColor = &HC0& Else Shape2(j).BackColor = &HE0E0E0 End If Next j Case 6 '读S0.0—S0.7 read1 = Val("&H" + Mid(Right(read, 6), 1, 2)) wei(0) = dec2bin(read1) '调用十二进转二进制过程 For j = 0 To 7 If Mid(wei(0), 8 - j, 1) = "1" Then Shape3(j).BackColor = &HC0& Command2(j).Caption = "S0." + Trim(j) + "复位" Else Shape3(j).BackColor = &HE0E0E0 Command2(j).Caption = "S0." + Trim(j) + "置位" End If Next j Case 7 '读C0 read1 = Val("&H" + Mid(Right(read, 8), 1, 4)) Text3.Text = read1 'C当前值显示 i = -1 '常规读取全部完成,从头开始,因为下面有一个+1命令,所以此处赋-1 End Select i = i + 1 '进行下一个类型的常规读取 读操作 = False '读操作接收处理完成 Shape6.BackColor = &HC0& Timer1.Enabled = True '进行下一个类型的常规读取 Timer2.Enabled = False End If End If '判断第一组发送命令结束 End If End Sub ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Private Sub Timer1_Timer() 第一次 = True MSComm1.RThreshold = 1 '因为PLC接收到写或是置位命令,只返回一个字符,所以设为1(RThreshold:定义接收缓冲区接收多少个字符后产生COMMFX_OnComm事件) If 非读操作 = True Then '如果有非读命令存在 Select Case 何种非读操作 Case 0 ReDim str_write(0 To 37) As Byte '重新定义数组 str_write(0) = &H68 str_write(1) = &H20 str_write(2) = &H20 str_write(3) = &H68 str_write(4) = &H2 str_write(5) = &H0 str_write(6) = lie2 '类型 str_write(7) = &H32 str_write(8) = &H1 str_write(9) = &H0 str_write(10) = &H0 str_write(11) = &H0 str_write(12) = &H0 str_write(13) = &H0 str_write(14) = &HE str_write(15) = &H0 str_write(16) = &H5 str_write(17) = &H5 str_write(18) = &H1 str_write(19) = &H12 str_write(20) = &HA str_write(21) = &H10 str_write(22) = &H1 str_write(23) = &H0 str_write(24) = &H1 str_write(25) = &H0 str_write(26) = lie1 '存储器类型,01:V存储器 00:其它 str_write(27) = lie '读不同元件的代码 str_write(28) = &H0 str_write(29) = &H0 str_write(30) = dz str_write(31) = &H0 str_write(32) = &H3 str_write(33) = &H0 str_write(34) = &H1 str_write(35) = SRet '置/复位 str_write(36) = SumChk(str_write) str_write(37) = &H16 End Select Else ' 如果没有非读命令则执行常规轮询 读操作 = True '置真的目的:当有非读命令而读操作的接收处理没有完成时,先完成读命令的接收处理 Select Case i Case 0 '读M0.0—M0.7 ReDim str_write(0 To 32) As Byte '重新定义数组 str_write(0) = &H68 str_write(1) = &H1B str_write(2) = &H1B str_write(3) = &H68 str_write(4) = &H2 str_write(5) = &H0 str_write(6) = &H6C str_write(7) = &H32 str_write(8) = &H1 str_write(9) = &H0 str_write(10) = &H0 str_write(11) = &H0 str_write(12) = &H0 str_write(13) = &H0 str_write(14) = &HE str_write(15) = &H0 str_write(16) = &H0 str_write(17) = &H4 '读 str_write(18) = &H1 str_write(19) = &H12 str_write(20) = &HA str_write(21) = &H10 str_write(22) = &H2 '读取位,字节,字,双字(1,2,4,8) str_write(23) = &H0 str_write(24) = &H1 '以字节为单位,连续读取的字节数 str_write(25) = &H0 str_write(26) = &H0 '存储器类型,01:V存储器 00:其它 str_write(27) = &H83 '读不同元件的代码 str_write(28) = &H0 str_write(29) = &H0 '高位地址 地址转换地16进制 (字节号*8+位号)\256 str_write(30) = &H0 '低位地址 地址转换地16进制 (字节号*8+位号)Mod 256 str_write(31) = SumChk(str_write) str_write(32) = &H16 Case 1 '读T0 ReDim str_write(0 To 32) As Byte '重新定义数组 str_write(0) = &H68 str_write(1) = &H1B str_write(2) = &H1B str_write(3) = &H68 str_write(4) = &H2 str_write(5) = &H0 str_write(6) = &H7C str_write(7) = &H32 str_write(8) = &H1 str_write(9) = &H0 str_write(10) = &H0 str_write(11) = &H0 str_write(12) = &H8 '&H8 str_write(13) = &H0 str_write(14) = &HE str_write(15) = &H0 str_write(16) = &H0 str_write(17) = &H4 '读 str_write(18) = &H1 str_write(19) = &H12 str_write(20) = &HA str_write(21) = &H10 str_write(22) = &H1F '读取位,字节,字,双字(1,2,4,8) str_write(23) = &H0 str_write(24) = &H1 '读取数据个数 str_write(25) = &H0 str_write(26) = &H0 '存储器类型,01:V存储器 00:其它 str_write(27) = &H1F '读不同元件的代码 str_write(28) = &H0 str_write(29) = &H0 '高位地址 地址转换地16进制 (字节号*8+位号)\256 str_write(30) = &H0 '低位地址 地址转换地16进制 (字节号*8+位号)Mod 256 str_write(31) = SumChk(str_write) str_write(32) = &H16 Case 2 '读V0.0—V0.7 ReDim str_write(0 To 32) As Byte '重新定义数组 str_write(0) = &H68 str_write(1) = &H1B str_write(2) = &H1B str_write(3) = &H68 str_write(4) = &H2 str_write(5) = &H0 str_write(6) = &H6C str_write(7) = &H32 str_write(8) = &H1 str_write(9) = &H0 str_write(10) = &H0 str_write(11) = &H0 str_write(12) = &H0 str_write(13) = &H0 str_write(14) = &HE str_write(15) = &H0 str_write(16) = &H0 str_write(17) = &H4 '读 str_write(18) = &H1 str_write(19) = &H12 str_write(20) = &HA str_write(21) = &H10 str_write(22) = &H2 '读取位,字节,字,双字(1,2,4,8) str_write(23) = &H0 str_write(24) = &H1 '读取数据个数 str_write(25) = &H0 str_write(26) = &H1 '存储器类型,01:V存储器 00:其它 str_write(27) = &H84 '读不同元件的代码 str_write(28) = &H0 str_write(29) = &H0 '高位地址 地址转换地16进制 (字节号*8+位号)\256 str_write(30) = &H0 '低位地址 地址转换地16进制 (字节号*8+位号)Mod 256 str_write(31) = SumChk(str_write) str_write(32) = &H16 Case 3 '读输入 ReDim str_write(0 To 32) As Byte '重新定义数组 str_write(0) = &H68 str_write(1) = &H1B str_write(2) = &H1B str_write(3) = &H68 str_write(4) = &H2 str_write(5) = &H0 str_write(6) = &H6C str_write(7) = &H32 str_write(8) = &H1 str_write(9) = &H0 str_write(10) = &H0 str_write(11) = &H0 str_write(12) = &H0 str_write(13) = &H0 str_write(14) = &HE str_write(15) = &H0 str_write(16) = &H0 str_write(17) = &H4 '读 str_write(18) = &H1 str_write(19) = &H12 str_write(20) = &HA str_write(21) = &H10 str_write(22) = &H2 '读取位,字节,字,双字(1,2,4,8) str_write(23) = &H0 str_write(24) = &H2 '读取数据个数 str_write(25) = &H0 str_write(26) = &H0 '存储器类型,01:V存储器 00:其它 str_write(27) = &H81 '读不同元件的代码 str_write(28) = &H0 str_write(29) = &H0 '高位地址 地址转换地16进制 (字节号*8+位号)\256 str_write(30) = &H0 '低位地址 地址转换地16进制 (字节号*8+位号)Mod 256 str_write(31) = SumChk(str_write) str_write(32) = &H16 Case 4 '读VW0—VW15 ReDim str_write(0 To 32) As Byte '重新定义数组 str_write(0) = &H68 str_write(1) = &H1B str_write(2) = &H1B str_write(3) = &H68 str_write(4) = &H2 str_write(5) = &H0 str_write(6) = &H6C str_write(7) = &H32 str_write(8) = &H1 str_write(9) = &H0 str_write(10) = &H0 str_write(11) = &H0 str_write(12) = &H0 str_write(13) = &H0 str_write(14) = &HE str_write(15) = &H0 str_write(16) = &H0 str_write(17) = &H4 '读 str_write(18) = &H1 str_write(19) = &H12 str_write(20) = &HA str_write(21) = &H10 str_write(22) = &H2 '读取位,字节,字,双字(1,2,4,8) str_write(23) = &H0 str_write(24) = &H20 '以字节为单位,连续读取的字节数 str_write(25) = &H0 str_write(26) = &H1 '存储器类型,01:V存储器 00:其它 str_write(27) = &H84 '读不同元件的代码 str_write(28) = &H0 str_write(29) = &H0 '高位地址 地址转换地16进制 (字节号*8+位号)\256 str_write(30) = &H0 '低位地址 地址转换地16进制 (字节号*8+位号)Mod 256 str_write(31) = SumChk(str_write) str_write(32) = &H16 Case 5 '读输出 ReDim str_write(0 To 32) As Byte '重新定义数组 str_write(0) = &H68 str_write(1) = &H1B str_write(2) = &H1B str_write(3) = &H68 str_write(4) = &H2 str_write(5) = &H0 str_write(6) = &H6C str_write(7) = &H32 str_write(8) = &H1 str_write(9) = &H0 str_write(10) = &H0 str_write(11) = &H0 str_write(12) = &H0 str_write(13) = &H0 str_write(14) = &HE str_write(15) = &H0 str_write(16) = &H0 str_write(17) = &H4 '读 str_write(18) = &H1 str_write(19) = &H12 str_write(20) = &HA str_write(21) = &H10 str_write(22) = &H2 '读取位,字节,字,双字(1,2,4,8) str_write(23) = &H0 str_write(24) = &H2 '读取数据个数 str_write(25) = &H0 str_write(26) = &H0 '存储器类型,01:V存储器 00:其它 str_write(27) = &H82 '读不同元件的代码 str_write(28) = &H0 str_write(29) = &H0 '高位地址 地址转换地16进制 (字节号*8+位号)\256 str_write(30) = &H0 '低位地址 地址转换地16进制 (字节号*8+位号)Mod 256 str_write(31) = SumChk(str_write) str_write(32) = &H16 Case 6 '读S0.0—S0.7 ReDim str_write(0 To 32) As Byte '重新定义数组 str_write(0) = &H68 str_write(1) = &H1B str_write(2) = &H1B str_write(3) = &H68 str_write(4) = &H2 str_write(5) = &H0 str_write(6) = &H6C str_write(7) = &H32 str_write(8) = &H1 str_write(9) = &H0 str_write(10) = &H0 str_write(11) = &H0 str_write(12) = &H0 str_write(13) = &H0 str_write(14) = &HE str_write(15) = &H0 str_write(16) = &H0 str_write(17) = &H4 '读 str_write(18) = &H1 str_write(19) = &H12 str_write(20) = &HA str_write(21) = &H10 str_write(22) = &H2 '读取位,字节,字,双字(1,2,4,8) str_write(23) = &H0 str_write(24) = &H1 '读取数据个数 str_write(25) = &H0 str_write(26) = &H0 '存储器类型,01:V存储器 00:其它 str_write(27) = &H4 '读不同元件的代码 str_write(28) = &H0 str_write(29) = &H0 '高位地址 地址转换地16进制 (字节号*8+位号)\256 str_write(30) = &H0 '低位地址 地址转换地16进制 (字节号*8+位号)Mod 256 str_write(31) = SumChk(str_write) str_write(32) = &H16 Case 7 '读C0 ReDim str_write(0 To 32) As Byte '重新定义数组 str_write(0) = &H68 str_write(1) = &H1B str_write(2) = &H1B str_write(3) = &H68 str_write(4) = &H2 str_write(5) = &H0 str_write(6) = &H7C str_write(7) = &H32 str_write(8) = &H1 str_write(9) = &H0 str_write(10) = &H0 str_write(11) = &H0 str_write(12) = &H12 '&H8 str_write(13) = &H0 str_write(14) = &HE str_write(15) = &H0 str_write(16) = &H0 str_write(17) = &H4 '读 str_write(18) = &H1 str_write(19) = &H12 str_write(20) = &HA str_write(21) = &H10 str_write(22) = &H1E '读取位,字节,字,双字(1,2,4,8) str_write(23) = &H0 str_write(24) = &H1 '读取数据个数 str_write(25) = &H0 str_write(26) = &H0 '存储器类型,01:V存储器 00:其它 str_write(27) = &H1E '读不同元件的代码 str_write(28) = &H0 str_write(29) = &H0 '高位地址 地址转换地16进制 (字节号*8+位号)\256 str_write(30) = &H0 '低位地址 地址转换地16进制 (字节号*8+位号)Mod 256 str_write(31) = SumChk(str_write) str_write(32) = &H16 End Select End If MSComm1.InBufferCount = 0 MSComm1.OutBufferCount = 0 MSComm1.Output = str_write '发送命令 ik = 0 Timer1.Enabled = False '等待接收处理结束后再进行下一次的命令发送 Timer2.Enabled = True Text5 = "0" Shape6.BackColor = &HE0E0E0 End Sub ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Private Sub Timer2_Timer() ik = ik + 1 If ik > 3 And Timer1.Enabled = False Then Timer1.Enabled = True End If End Sub ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3