三菱PLC 內部寄存器 通信 地址計算 算法

    首先將需要讀取的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
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章