獻(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)
2020-9-9 09:20 上傳
點(diǎn)擊文件名下載附件
VB與松下PLC通信程序?qū)W習(xí).docx
|