找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 3437|回復(fù): 1
收起左側(cè)

VB與松下PLC通信程序?qū)W習(xí)資料

[復(fù)制鏈接]
ID:817370 發(fā)表于 2020-9-9 09:20 | 顯示全部樓層 |閱讀模式
獻(xiàn)給有需要的人

這就是COM口圖標(biāo)。從Private Sub Form_Load()說(shuō)起,在這個(gè)Form_Load()中先檢查COM口是否打開。If FP0.PortOpen = True Then FP0.PortOpen = False,這就是若com口是打開的,就先把com口關(guān)閉,這樣是為了好去調(diào)試com口。FP0.CommPort = 1,這個(gè)設(shè)置com口為1。FP0.Settings = "9600,o,8,1,波特率9600,位數(shù)8,停止位1。FP0.InputLen = 0 ,InputLen設(shè)為0就是讀出緩沖區(qū)的所有內(nèi)容。FP0.OutBufferCount = 0 ,清空發(fā)送緩沖區(qū),就是在接收之前清空緩沖區(qū)。FP0.InBufferCount = 0,清空接收緩沖區(qū)。FP0.PortOpen = True,com口開啟。     這就是COM口的通信參數(shù)設(shè)置。
校驗(yàn)計(jì)算程序:
    之前是比較基礎(chǔ)的com口參數(shù)的設(shè)置,這次的校驗(yàn)計(jì)算程序是用來(lái)進(jìn)行對(duì)傳送數(shù)據(jù)的奇校驗(yàn)或者偶校驗(yàn),程序上設(shè)置的是為偶校驗(yàn)。Function FCS(a$) As String,聲明FCS(a$)設(shè)置為字符型,在任何模塊中都可被調(diào)用。b% = 0,設(shè)置b%為0。 I% = Len(a$),a$的字符串長(zhǎng)度。
    For I = 1 To I%
      b% = b% Xor Asc(Mid(a$, I, 1)),一個(gè)FOR循環(huán),根據(jù)字符長(zhǎng)度開進(jìn)行循環(huán)。Mid(a$, I, 1),把a(bǔ)$的第I位取1個(gè)字符。 Asc(Mid(a$, I, 1)),把這個(gè)字符轉(zhuǎn)換成Asc碼。之后b%與之異或。在松下PLC的通信協(xié)議中,在校驗(yàn)中要把每一位的Asc碼進(jìn)行異或求和后生成,所以此程序若有五位,就必須異或五次,把最后的異或求和的數(shù)據(jù)送入ff$,(ff$ = Hex$(b%)),Hex的作用是把數(shù)據(jù)轉(zhuǎn)換成16位的數(shù)據(jù)。
If Len(ff$) = 1 Then
     ff$ = "0" + ff$
這條程序就是檢測(cè)最后異或求和的數(shù)據(jù)有幾位,等于1的話就是一位,而最后的校驗(yàn)碼應(yīng)該是兩位,所以需要ff$ = "0" + ff$。最后FCS = ff$,這就是最后的一步,是所有模塊都可以進(jìn)行調(diào)用。
首先我們要在通用聲明模塊中進(jìn)行聲明:Dim 操作類型 As Integer,將操作類型定義為整數(shù)。
Dim Sendata As String,將Sendata定義為字符串。
Sendata = "#RDD0000100001",根據(jù)通信協(xié)議發(fā)送數(shù)據(jù)(%起始碼、01為PLC站號(hào)、RD為讀取寄存器指令,D0000100001,數(shù)據(jù)代碼D,起始數(shù)據(jù)編碼00001,結(jié)束數(shù)據(jù)編碼00001)。
FP0.RThreshold = 13,接收到13個(gè)字節(jié)數(shù)據(jù)就立即觸發(fā)OnComm()事。
Sendata = Sendata + FCS(Sendata) + vbCr,意思是Sendata = #RDD0000100001+調(diào)用校驗(yàn)碼程序的結(jié)果+vbCr(vbCr是回車的意思,回到本行的開頭,意思不是特別懂)。
操作類型 = 1,這個(gè)后面再說(shuō)。
FP0.InBufferCount = 0,在發(fā)送數(shù)據(jù)之前清空接收緩沖區(qū)。
FP0.OutBufferCount = 0,在發(fā)送數(shù)據(jù)之前清空發(fā)送緩沖區(qū)。
FP0.Output = Sendata,向PLC發(fā)送數(shù)據(jù)。
Dim Sendata As String ,定義Sendata為字符串。
Dim Devdat1 As String,定義Devdat1為字符串。
If CDbl(Val(Text2.Text)) > 32767 Then: MsgBox ("數(shù)值超限!"): Exit Sub,CDbl為把數(shù)值轉(zhuǎn)換為雙精度浮點(diǎn)數(shù)據(jù)類型。Val是將字符串?dāng)?shù)據(jù)類型轉(zhuǎn)換為數(shù)值型數(shù)據(jù)類型。32767(2的15開方)是不允許輸入的數(shù)據(jù)超過(guò)16位。
Devdat1 = Right("00000000" + Hex(Val(Text2.Text)), 4),Hex就是使數(shù)值返回16進(jìn)制數(shù)值。("00000000" + Hex(Val(Text2.Text)),湊成16位數(shù)。Right去后面的4位。
Devdat1 = Right(Devdat1, 2) + Left(Devdat1, 2),數(shù)據(jù)的寫入格式為先低位后高位。
Devdat1 = Devdat1
FP0.RThreshold = 9,接收9位字符數(shù)就觸發(fā)OnComm()事。
Sendata = "#WDD0000100001" + Devdat1,發(fā)送數(shù)據(jù)的地址+要寫入的數(shù)據(jù)。
操作類型 = 2
FP0.InBufferCount = 0 '清空接收緩沖區(qū)
FP0.OutBufferCount = 0 '清空發(fā)送緩沖區(qū)
FP0.Output = Sendata + FCS(Sendata) + vbCr。
Dim Sendata As String
FP0.RThreshold = 9
Sendata = "#WCSR00011,WCS單觸點(diǎn)寫入。R0001指令代碼+觸點(diǎn)編號(hào)。1最后的1是觸點(diǎn)ON。
操作類型 = 3
FP0.InBufferCount = 0 '清空接收緩沖區(qū)
FP0.OutBufferCount = 0 '清空發(fā)送緩沖區(qū)
FP0.Output = Sendata + FCS(Sendata) + vbCr
Dim Sendata As String
FP0.RThreshold = 9
Sendata = "#WCSR00010",跟第五章一樣,只是最后以為是0,0是狀態(tài)OFF。
操作類型 = 4
FP0.InBufferCount = 0 '清空接收緩沖區(qū)
FP0.OutBufferCount = 0 '清空發(fā)送緩沖區(qū)
FP0.Output = Sendata + FCS(Sendata) + vbCr
Dim Sendata As String
FP0.RThreshold = 10
Sendata = "#RCP1R0001"RCP為讀取多觸點(diǎn)狀態(tài),之后的1為觸點(diǎn)編號(hào)。R0001為觸點(diǎn)代碼編號(hào)。
操作類型 = 5
FP0.InBufferCount = 0 '清空接收緩沖區(qū)
FP0.OutBufferCount = 0 '清空發(fā)送緩沖區(qū)
FP0.Output = Sendata + FCS(Sendata) + vbCr
COM主程序:
Private Sub FP0_OnComm(),當(dāng)接收到一定數(shù)目的FP0.RThreshold=X,就會(huì)觸發(fā)此COM。
Dim getData As String '
Dim station1
Dim station2
Dim M1data As Integer
If FP0.CommEvent = comEvReceive Then,CommEvent 是判斷 MSComm控件的當(dāng)前狀態(tài)。 comEvReceive 是收到 Rthreshold 個(gè)字符。
getData = FP0.Input ,讀取接收緩沖內(nèi)容。
Select Case 操作類型,選擇操作類型。
Case 1,如果是讀取DT1.
getData = Mid(getData, 7, 4),讀取第7位(包括第七位)的四位,這四位就是觸點(diǎn)的數(shù)據(jù)。
station1 = Right(getData, 2) ,因?yàn)橹暗乃奈粩?shù)據(jù)是先低后高,所以這邊先取高位。
station2 = Left(getData, 2),取低位。
getData = station1 + station2 ,先高后低。
getData = Val("&H" + getData),十六進(jìn)制轉(zhuǎn)換為十進(jìn)制。
Text1.Text = CStr(getData), 顯示在Text1里。
Case 2 ,如果是寫DT1。
If Mid(getData, 4, 1) = "$" Then                             getDate前面定義就是FP0.input,當(dāng)接受PLC                         Label1.Caption = "寫入成功"                                 發(fā)出的數(shù)據(jù)的第四位為$時(shí),就說(shuō)明了數(shù)據(jù)發(fā)送
                  Else                                                      成功,否則就是失敗的。這里的程序就是就是這樣的。
                     Label1.Caption = "寫入失敗"
                  End If
Case 3 '如果是置位R1
                  If Mid(getData, 4, 1) = "$" Then
                     Label2.Caption = "置位成功"
                  Else
                     Label2.Caption = "置位失敗"
                  End If
Case 4 '如果是復(fù)位R1
                  If Mid(getData, 4, 1) = "$" Then
                     Label2.Caption = "復(fù)位成功"
                  Else
                     Label2.Caption = "復(fù)位失敗"
                  End If
             Case 5 '如果是讀取R1的狀態(tài)
                  If Mid(getData, 7, 1) = 1 Then
                     Label3.Caption = "ON"
                  Else
                     Label3.Caption = "OFF"
                  End If
      End Select
以上。
從第九章開始就是真正意義上的自動(dòng)監(jiān)控程序的學(xué)習(xí):
Dim 非實(shí)時(shí)監(jiān)控通訊 As Boolean,對(duì)非實(shí)時(shí)監(jiān)控通信定義為布爾。
Dim 何種非實(shí)時(shí)監(jiān)控通訊 As String,何種非實(shí)時(shí)監(jiān)控通信定義為字符串。
Dim 實(shí)時(shí)監(jiān)控通訊 As Boolean ,實(shí)時(shí)監(jiān)控通訊定義為布爾。
Dim j As Integer ,j定義為整型。
Dim Sendata As String ,Sendata定義為字符串。
Dim yuanji As String ,yuanji定義為字符串。
Dim zhuang As String ,zhuang定義為字符串。
Dim devdat As String ,devdat定義為字符串。
Dim setad As String ,setad定義為字符串。
Dim caoxian As Boolean ,caoxian定義為布爾。
Dim awe1 As Integer ,awe1定義為整型。
Dim errT As Boolean ,errT定義為布爾。
在通用聲明里對(duì)這些變量進(jìn)行聲明。
Private Sub Combo2_Click() ,通訊超時(shí)的選擇
Timer2.Interval = (Combo2.ListIndex + 1) * 1000 ,檢測(cè)時(shí)間為s,而計(jì)時(shí)器的單位為ms,所以要乘以1000。ListIndex為項(xiàng)目的索引值,第一個(gè)ListIndex等于0,所以必須+ 1。
End Sub
Private Sub Combo1_Click() ,通訊口的選擇。
errT = True ,通訊口錯(cuò)誤。
Call CommSet ,調(diào)用通訊口設(shè)置過(guò)程。
End Sub
對(duì)COM口參數(shù)進(jìn)行設(shè)置:
Private Sub CommSet()
    On Error GoTo err1 ,On Error是個(gè)錯(cuò)誤處理程序,On Error GoTo err1語(yǔ)句就是啟動(dòng)錯(cuò)誤處理程序從指定的err1開始。
    If fp0.PortOpen = True Then fp0.PortOpen = False ,如果通訊口已打開,則先關(guān)閉通訊口。開始通訊口設(shè)置工作。
    fp0.CommPort = Combo1.ListIndex + 1 ,索引值+1就是所選的COM。
    fp0.Settings = "9600,o,8,1"
    fp0.InputLen = 0
    fp0.OutBufferCount = 0
    fp0.InBufferCount = 0
    fp0.PortOpen = True ,打開通訊口。
    errT = False ,不存在錯(cuò)誤。
    Exit Sub
err1:
  MsgBox Err.Description ,錯(cuò)誤提示。
End Sub
Private Sub Command9_Click()
  setad = UCase(Text3.Text) ,UCase的作用是將小寫字母轉(zhuǎn)換為大寫字母,Text3.Text為輸入的文本。
  setad = Right("0000" + CStr(setad), 4) ,CStr(setad)的作用是將setad轉(zhuǎn)換為字符串型,Right就是去數(shù)據(jù)右邊的4位。
  If setad = "" Then ,""為VB的空字符。
     MsgBox ("請(qǐng)輸入元件地址!")
     Text3.SetFocus ,Text3置為焦點(diǎn)。
     Exit Sub
  End If
  非實(shí)時(shí)監(jiān)控通訊 = True ,為真。
  何種非實(shí)時(shí)監(jiān)控通訊 = "查詢"
  Select Case zhuang ,zhuang為置/復(fù)位,位狀態(tài)查詢?cè)䴓?biāo)志。
         Case "X" ,zhuang為X。
              Sendata = "#RCP1X" + setad ,%為指令指定的,01為站號(hào),RCP為讀取多觸點(diǎn)狀態(tài),1為觸點(diǎn)數(shù)目(n=1-8),X為觸點(diǎn)代碼,setad就是觸點(diǎn)編號(hào)。下面也是一樣的道理。
         Case "Y" ,zhuang為Y。
              Sendata = "#RCP1Y" + setad
         Case "R" ,zhuang為R。
              Sendata = "#RCP1R" + setad
  End Select
End Sub
Private Sub Command8_Click()
  setad = UCase(Text3.Text)
  setad = Right("0000" + CStr(setad), 4)
  If setad = "" Then
     MsgBox ("請(qǐng)輸入元件地址!")
     Text3.SetFocus
     Exit Sub
  End If
  非實(shí)時(shí)監(jiān)控通訊 = True
  何種非實(shí)時(shí)監(jiān)控通訊 = "置位"
  Select Case zhuang
         Case "X"
              Sendata = "#WCSX" + setad + "1" ,WCS為寫入單觸點(diǎn)狀態(tài),setad為觸點(diǎn)編號(hào),"1"為觸點(diǎn)數(shù)據(jù),狀態(tài)為ON。
         Case "Y"
              Sendata = "#WCSY" + setad + "1"
         Case "R"
              Sendata = "#WCSR" + setad + "1"
  End Select
End Sub
Private Sub Command7_Click()
  setad = UCase(Text3.Text)
  setad = Right("0000" + CStr(setad), 4)
  If setad = "" Then
     MsgBox ("請(qǐng)輸入元件地址!")
     Text3.SetFocus
     Exit Sub
  End If
  非實(shí)時(shí)監(jiān)控通訊 = True
  何種非實(shí)時(shí)監(jiān)控通訊 = "置位"
  Select Case zhuang
         Case "X"
              Sendata = "#WCSX" + setad + "0"
         Case "Y"
              Sendata = "#WCSY" + setad + "0"
         Case "R"
              Sendata = "#WCSR" + setad + "0"
  End Select
End Sub
Private Sub Form_Unload(Cancel As Integer)
End ,End就是退出。
End Sub
Private Sub Option8_Click()
zhuang = "X"
End Sub
Private Sub Option10_Click()
zhuang = "R"
End Sub
Private Sub Command1_Click()
     非實(shí)時(shí)監(jiān)控通訊 = True
     Sendata = "#RMR" ,Sendata為發(fā)送數(shù)據(jù)命令,RM為遙控命令,R為PROG到RUN模式。
     何種非實(shí)時(shí)監(jiān)控通訊 = "運(yùn)行"
End Sub
Private Sub Command2_Click()
     非實(shí)時(shí)監(jiān)控通訊 = True
     Sendata = "#RMP" ,P為RUN到PROG模式。
     何種非實(shí)時(shí)監(jiān)控通訊 = "運(yùn)行"
End Sub
校驗(yàn)計(jì)算程序是用來(lái)進(jìn)行對(duì)傳送數(shù)據(jù)的奇校驗(yàn)或者偶校驗(yàn),程序上設(shè)置的是為偶校驗(yàn)。
Function FCS(a$) As String 聲明FCS(a$)設(shè)置為字符型,在任何模塊中都可被調(diào)用。
  b% = 0
I% = Len(a$)  ,a$的字符串長(zhǎng)度。
  For I = 1 To I% ,一個(gè)FOR循環(huán),根據(jù)字符長(zhǎng)度開進(jìn)行循環(huán)。
      b% = b% Xor Asc(Mid(a$, I, 1)) ,Mid(a$, I, 1),把a(bǔ)$的第I位取1個(gè)字符。 Asc(Mid(a$, I, 1)),把這個(gè)字符轉(zhuǎn)換成Asc碼。之后b%與之異或。
  Next
  ff$ = Hex$(b%)  ,Hex的功能是轉(zhuǎn)換為十六進(jìn)制數(shù)值。
  If Len(ff$) = 1 Then
     ff$ = "0" + ff$
  End If
  FCS = ff$
End Function
Private Sub Command5_Click(index As Integer) ,讀或者寫。
Dim Devadd As String, Devadd1 As String ,Devadd是輸入地址的16位數(shù)據(jù),Devadd1是32位。
Dim Devdat1 As String
Dim station1
Dim station2
Dim station3
Dim station4
Dim station5
Dim station6
Dim setad As String, setad1 As String ,setad為輸入地址。
非實(shí)時(shí)監(jiān)控通訊 = True ,需要非實(shí)時(shí)監(jiān)控通訊狀態(tài)。
setad = Text1.Text ,讀取輸入的地址。
If setad = "" Then ,如果地址為空則提示。
MsgBox ("請(qǐng)輸入元件地址!") ,提示這個(gè)。
Text1.SetFocus ,text1控件取得焦點(diǎn)。
Exit Sub ,退出此事件。
End If
Devadd = Right("00000" + CStr(Val(setad)), 5) ,因?yàn)槠鋵?shí)數(shù)據(jù)編碼是五位,所以寄存器地址為后五位。
Devadd1 = Right("00000" + CStr(Val(Text1.Text) + 1), 5) ,是32位數(shù)據(jù)的時(shí)候需要兩個(gè)寄存器,分為高十六位和低十六位,其中高十六位在的寄存器地址是低十六位的寄存器地址的+1,所以CStr(Val(Text1.Text) + 1。
If index = 0 Then '如果是點(diǎn)擊的是讀按鈕,index是command5中的數(shù)組標(biāo)識(shí),index = 0就是讀取。
何種非實(shí)時(shí)監(jiān)控通訊 = "讀"
If Option3.Value = True Then ,如果是16位讀。
Sendata = "#RDD" + Devadd + Devadd ,讀取十六位數(shù)據(jù)。
Else
Sendata = "#RDD" + Devadd + Devadd1   ,讀三十二位數(shù)據(jù)。
End If
Else ,如果是點(diǎn)擊的是寫按鈕。
何種非實(shí)時(shí)監(jiān)控通訊 = "寫"
If Option3.Value = True Then
devdat = "#WDD" + Devadd + Devadd ,寫入十六位數(shù)據(jù)。
Else
devdat = "#WDD" + Devadd + Devadd1 ,寫入三十二位數(shù)據(jù)。
End If
If Option1.Value Then ,十進(jìn)制方式。
If Option4.Value = True Then ,三十二位寫入。
If CDbl(Val(Text2.Text)) > 2147483648# Then: MsgBox ("數(shù)值超限!"): Exit Sub ,CDbl為轉(zhuǎn)換為雙精度浮點(diǎn)型數(shù)據(jù)。若數(shù)值大于2147483648,則數(shù)值超限。Text2.Text為寫入數(shù)值,數(shù)值為16進(jìn)制四位數(shù)值,如00A3H。
Devdat1 = Right(("00000000" + Hex(Val(Text2.Text))), 8)
station1 = Right(Devdat1, 4) ,取數(shù)據(jù)的右四位。
           station2 = Left(Devdat1, 4) ,取數(shù)據(jù)的左四位。
           station3 = Right(station1, 2) ,右四位數(shù)據(jù)的右二位。
           station4 = Left(station1, 2) ,右四位數(shù)據(jù)的左二位。
           station1 = station3 + station4  ,數(shù)據(jù)的原始格式是左高右低,而PLC讀出和寫入的數(shù)據(jù)的格式是左低右高。
           station5 = Right(station2, 2) ,左四位數(shù)據(jù)的右二位。
           station6 = Left(station2, 2)  ,左四位數(shù)據(jù)的左二位。
           station2 = station5 + station6
           Devdat1 = station1 + station2
           Sendata = devdat + Devdat1 ,devadd就是DTn,而devadd1就是DTn+1,devdat =起始碼+目標(biāo)站號(hào)+#+指令名稱+DTn+DTn(DTn+DTn+1),Devdar1是要寫入的數(shù)據(jù)。
            Else  ,單字節(jié)寫入。
           If CDbl(Val(Text2.Text)) > 32767 Then: MsgBox ("數(shù)值超限"): Exit Sub
           Devdat1 = Right("00000000" + Hex(Val(Text2.Text)), 4)         
           Devdat1 = Right(Devdat1, 2) + Left(Devdat1, 2)
           Sendata = devdat + Devdat1        
           End If
        If Option4.Value = True Then
           If Val("&H" + Text2.Text) > 2147483648# Then: MsgBox ("數(shù)值超限"): Exit Sub ,&H為轉(zhuǎn)換為十進(jìn)制。例如:&H61=97。
           Devdat1 = Right("00000000" + Text2.Text, 8)
           station1 = Right(Devdat1, 4)
           station2 = Left(Devdat1, 4)
           station3 = Right(station1, 2)
           station4 = Left(station1, 2)
           station1 = station3 + station4
           station5 = Right(station2, 2)
           station6 = Left(station2, 2)
           station2 = station5 + station6
           Devdat1 = station1 + station2
           Sendata = devdat + Devdat1
        Else
           If Val("&H" + Text2.Text) > 32767 Then: MsgBox ("êy?μ3??T£?"): Exit Sub
           Devdat1 = Right("00000000" + Text2.Text, 4)
           Devdat1 = Right(Devdat1, 2) + Left(Devdat1, 2)
           Sendata = devdat + Devdat1
        End If
     End If
  End If
End Sub  
Private Sub Form_Load()
Dim g As Integer
For g = 1 To 10 ,添加通信選擇。
     Combo1.AddItem "Com" & Trim$(Str$(g)) ,添加Combo1項(xiàng)目10個(gè)。
Next g
For g = 1 To 10
     Combo2.AddItem g  ,添加Combo2項(xiàng)目10個(gè)。
Next g
Combo1.ListIndex = 0  ,默認(rèn)com1口。
Combo2.ListIndex = 0 ,默認(rèn)通訊超時(shí)5秒。
非實(shí)時(shí)監(jiān)控通訊 =  False
Option1.Value = True   ,默認(rèn)選擇十進(jìn)制。
Option3.Value = True   ,默認(rèn)選擇十六位讀寫方式。
Option10.Value = True  ,默認(rèn)選擇R。
yuanji = "DT" ,默認(rèn)選擇DT。
Timer1.Enabled = True  ,激活定時(shí)掃描。
Timer2.Enabled = False  ,通訊超時(shí)關(guān)閉。
End Sub
Private Sub fp0_OnComm()
Dim GetData As String
Dim k As Integer
Dim asd(3) As Integer
Dim wei(3) As String
Dim gfd As String
Dim xym(15) As String
If fp0.CommEvent = comEvReceive Then ,CommEvent的屬性返回的值為comEvReceive時(shí)發(fā)生了接收事件。
      Timer2.Enabled = False ,PLC有返回?cái)?shù)據(jù),定時(shí)器關(guān)閉。
      Label2.Caption = "通訊正常"
      GetData = fp0.Input ,讀取接收區(qū)緩沖內(nèi)容。
      Shape4.BackColor = &HC0& ,通訊狀態(tài)指示燈為紅色。
      If 非實(shí)時(shí)監(jiān)控通訊 = True And 實(shí)時(shí)監(jiān)控通訊 = False Then ,如果有非實(shí)時(shí)監(jiān)控通訊操作并且實(shí)時(shí)監(jiān)控通訊處理結(jié)束。
      非實(shí)時(shí)監(jiān)控通訊 = False ,清楚非實(shí)時(shí)監(jiān)控通訊標(biāo)識(shí)。
      Select Case 何種非實(shí)時(shí)監(jiān)控通訊
             Case "讀"
If Option3.Value = True Then ,16位讀。
                        GetData = Mid(GetData, 7, 4)
                        station1 = Right(GetData, 2)
                        station2 = Left(GetData, 2)
                        GetData = station1 + station2
                        If Option2.Value = True Then
                           Text2.Text = CStr(Right(Hex(Val("&H" + GetData)), 4)) ,&H表示括號(hào)內(nèi)為十六進(jìn)制數(shù)據(jù)。
                        Else
                           GetData = Val("&H" + GetData)
                           Text2.Text = CStr(GetData)
                        End If
Else '32位讀
                           GetData = Mid(GetData, 7, 8) ,讀回來(lái)的數(shù)據(jù)的順序是先低位后高位。
                           station1 = Right(GetData, 4)
                           station2 = Left(GetData, 4)
                           station3 = Right(station1, 2)
                           station4 = Left(station1, 2)
                           station5 = Right(station2, 2)
                           station6 = Left(station2, 2)
                           station1 = station3 + station4
                           station2 = station5 + station6
                           GetData = station1 + station2
                           Dim sdfg As Double
                           sdfg = "&H" + GetData ,字符串+數(shù)字=字符串。
                           If Option2.Value = True Then ,如果是以十進(jìn)制格式讀取數(shù)據(jù)。
                              Text2.Text = Hex(sdfg) ,
                           Else
                              Text2.Text = CStr(sdfg)
                           End If
                      End If
Case "查詢"
                     If Mid(GetData, 7, 1) = 1 Then
                        Shape8.BackColor = &HC0&
                     Else
                        Shape8.BackColor = &HE0E0E0
                     End If
End Select
Else
         Select Case j
                Case 0  ,讀DT0---DT4。
                     GetData = Mid(GetData, 7, 20) '從GetData變量代表的字符的左側(cè)開始的第七位開始取四個(gè)字符賦給GetData
                     Text6 = GetData
                     For k = 0 To 4
                         Text5(k).Text = Val("&H" + Mid(GetData, k * 4 + 3, 2) + Mid(GetData, k * 4 + 1, 2))  'Right的功能是從GetData變量代表的字符的右側(cè)開始取2個(gè)字符
                        
                     Next k
                Case 1 '讀R0---RF狀態(tài)
                     GetData = Mid(GetData, 7, 8) '從GetData變量代表的字符的左側(cè)開始的第七位開始取一個(gè)字符賦給GetData
                     Text6 = GetData
                     For k = 0 To 7
                         If Mid(GetData, k + 1, 1) = "1" Then
                            Shape3(k).BackColor = &HC0&
                         Else
                            Shape3(k).BackColor = &HE0E0E0
                         End If
                     Next k
Case 2, 3
                     GetData = Mid(GetData, 7, 4) '根據(jù)協(xié)議,左起第二位開始的八位是需要的數(shù)據(jù)。取出
                     asd(0) = Val("&H" + Mid(GetData, 1, 2)) '低位寄存器的低八位,并轉(zhuǎn)換為十進(jìn)制
                     asd(1) = Val("&H" + Mid(GetData, 3, 2)) '低位寄存器的高八位,并轉(zhuǎn)換為十進(jìn)制
                     For k = 0 To 1
                         wei(k) = dec2bin(asd(k)) '將讀取的數(shù)據(jù)轉(zhuǎn)換成二進(jìn)制
                     Next k
                     gfd = wei(1) + wei(0)  '將四組的八位二進(jìn)制合并在一起
                     Text6 = gfd
                     '協(xié)議規(guī)定返回的PLC是從低位到高位排列,所以先提取出的放在后面
                     '如讀D0的雙字,那么返回來(lái)的順序是:D0的低八位,D0的高八位,D1的低八位,D1的高八位
                     '如,D0雙字節(jié)的數(shù)=2685674341,它的十六進(jìn)制=A0142365。那么在讀取過(guò)程中時(shí)PLC返回此數(shù)據(jù)的順序?yàn)椋?52314A0
                     For k = 0 To 15
                         xym(k) = Mid(gfd, 16 - k, 1) '讀取各位的狀態(tài)
                         If xym(k) = "1" Then '如果為1,說(shuō)明相應(yīng)的位為吸合狀態(tài)
                            Select Case j
                                   Case 2
                                        Shape1(k).BackColor = &HC0& '如果為讀取輸入(X)的狀態(tài)
                                   Case 3
                                        Shape2(k).BackColor = &HC0& '如果為讀取輸出(Y)的狀態(tài)
                            End Select
                         Else
                            Select Case j
                                   Case 2
                                        Shape1(k).BackColor = &HE0E0E0 '如果為讀取輸入(X)的狀態(tài)
                                   Case 3
                                        Shape2(k).BackColor = &HE0E0E0 '如果為讀取輸出(Y)的狀態(tài)
                            End Select
                         End If
                     Next k
Case 4   '讀PLC的當(dāng)前狀態(tài)
                     GetData = Mid(GetData, 14, 1) '從GetData變量代表的字符的左側(cè)開始的第14位開始取1個(gè)字符賦給GetData
                     Text6 = GetData
                     If Val(GetData) Mod 2 = "1" Then
                        Picture1(0).BackColor = &HFF&
                        Picture1(1).BackColor = &H80000005
                     Else
                        Picture1(0).BackColor = &H80000005
                        Picture1(1).BackColor = &HFF&
                     End If
                     j = -1 '計(jì)數(shù)器清零,開始下一次實(shí)時(shí)監(jiān)控循環(huán),下面有一個(gè)j=j+1,為了保證清零,所以賦的是-1
           End Select
           j = j + 1 '進(jìn)行本次循環(huán)的下一步通訊
           實(shí)時(shí)監(jiān)控通訊 = False '實(shí)時(shí)監(jiān)控通訊處理完畢
           Timer1.Enabled = True '打開定時(shí)通訊掃描
      End If
End If
End Sub
Private Sub Timer1_Timer() '實(shí)時(shí)監(jiān)控
  If errT = True Then '如果通訊口錯(cuò)誤
     Label2.Caption = "您的電腦沒(méi)有此通訊口"
     Exit Sub
  End If
  Shape4.BackColor = &HE0E0E0
  If 非實(shí)時(shí)監(jiān)控通訊 = True Then
     Select Case 何種非實(shí)時(shí)監(jiān)控通訊
            Case "讀"
                 If Option3.Value = True Then '十六進(jìn)制
                    fp0.RThreshold = 13 '設(shè)定產(chǎn)生OnComm事件的接收緩沖區(qū)字符數(shù)
                 Else
                    fp0.RThreshold = 17 '設(shè)定產(chǎn)生OnComm事件的接收緩沖區(qū)字符數(shù)
                 End If
            Case "查詢"
                 fp0.RThreshold = 10 '設(shè)定產(chǎn)生OnComm事件的接收緩沖區(qū)字符數(shù)
            Case "寫", "置位", "復(fù)位"
                 fp0.RThreshold = 9 '設(shè)定產(chǎn)生OnComm事件的接收緩沖區(qū)字符數(shù)
            Case "運(yùn)行"
                 fp0.RThreshold = 9 '設(shè)定產(chǎn)生OnComm事件的接收緩沖區(qū)字符數(shù)
     End Select
  Else
     實(shí)時(shí)監(jiān)控通訊 = True
     Select Case j '作用:實(shí)時(shí)監(jiān)控共需要五次才能完成一個(gè)實(shí)時(shí)監(jiān)控通訊循環(huán),每次j+1來(lái)判斷應(yīng)該發(fā)送第幾次命令
            Case 0    '讀DT0----DT4
                 Sendata = "#RDD0000000004" '根據(jù)協(xié)議要求發(fā)送代碼
                 fp0.RThreshold = 29 '設(shè)定產(chǎn)生OnComm事件的接收緩沖區(qū)字符數(shù)
            Case 1    '讀R0---RF狀態(tài)
                 Sendata = "#RCP8R0000R0001R0002R0003R0004R0005R0006R0007"
                 fp0.RThreshold = 17 '設(shè)定產(chǎn)生OnComm事件的接收緩沖區(qū)字符數(shù)
            Case 2    '讀輸入點(diǎn)狀態(tài)
                 Sendata = "#RCCX00000000"
                 fp0.RThreshold = 13 '設(shè)定產(chǎn)生OnComm事件的接收緩沖區(qū)字符數(shù)
            Case 3    '讀輸出點(diǎn)狀態(tài)
                 Sendata = "#RCCY00000000"
                 fp0.RThreshold = 13 '設(shè)定產(chǎn)生OnComm事件的接收緩沖區(qū)字符數(shù)
            Case 4    '讀PLC的當(dāng)前狀態(tài)
                 Sendata = "#RT"
                 fp0.RThreshold = 25 '設(shè)定產(chǎn)生OnComm事件的接收緩沖區(qū)字符數(shù)
     End Select
   
  End If
  Sendata = Sendata + FCS(Sendata) + vbCr 'FCS(fs)是調(diào)用校驗(yàn)和程序
  fp0.InBufferCount = 0
  fp0.OutBufferCount = 0
  fp0.Output = Sendata

  Timer1.Enabled = False '關(guān)閉定時(shí)通訊,等待PLC返回?cái)?shù)據(jù)。fp0_OnComm()事件處理完返回的數(shù)據(jù)后,再打開定時(shí)通訊
  Timer2.Enabled = True '打開與PLC通訊是否正常判斷定時(shí)器
  l = 0
End Sub
Private Sub Timer2_Timer() '如果發(fā)送命令結(jié)束后,在設(shè)定的通訊超時(shí)時(shí)間內(nèi)此定時(shí)器仍沒(méi)有關(guān)斷
      Label2.Caption = "通訊不正常" '通訊狀態(tài)指示
     j = 0
     Timer1.Enabled = True '打開定時(shí)通訊掃描
End Sub

以上內(nèi)容word格式下載: VB與松下PLC通信程序?qū)W習(xí).docx (83.76 KB, 下載次數(shù): 24)
回復(fù)

使用道具 舉報(bào)

ID:1006852 發(fā)表于 2022-3-7 16:35 | 顯示全部樓層
VB少有人用嗎?前一個(gè)資料也沒(méi)有看。這么好的資料沒(méi)有一個(gè)回復(fù)的。是不是沒(méi)有人用上位機(jī)聯(lián)PLC?
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表