|
|
先學(xué)51單片機(jī),后覺得232串口數(shù)據(jù)傳輸距離緊,繼續(xù)學(xué)modbus rtu協(xié)議。學(xué)著寫一個(gè)遠(yuǎn)程啟停程序,請(qǐng)指正,利于我提高。
'用遠(yuǎn)程IO模塊,4路輸入,4路輸出(常開、常閉)
'接觸器接通,斷開
'接觸器線圈接Y1常開用于啟動(dòng),接Y2常閉用于停止,輔助觸頭常開接X1,用于指示接觸器已經(jīng)吸合。
Option Explicit '強(qiáng)制顯式聲明
Dim Receiveover_shuzimokuai2 As Boolean '1號(hào)接收成功或失敗
'Dim Sendover As Boolean '發(fā)送完畢 comm事件
Dim sendshuzimokuai2(7) As Byte '數(shù)字模塊2發(fā)送查詢
Dim sendshuzimokuai2_Y1_c(7) As Byte '數(shù)字模塊2 Y1通 線圈接常開點(diǎn)用于啟動(dòng) c 代表closed
Dim sendshuzimokuai2_Y1_o(7) As Byte '數(shù)字模塊2 Y1斷 o 代表open
Dim sendshuzimokuai2_Y2_c(7) As Byte '數(shù)字模塊2 Y2通 線圈接常閉點(diǎn)用于停止
Dim sendshuzimokuai2_Y2_o(7) As Byte '數(shù)字模塊2 Y2斷
Public lunxun_jishu As Integer '輪詢計(jì)數(shù),此程序只有一個(gè)模塊,先串口發(fā)送查詢,下一秒分析串口回傳數(shù)據(jù)
Public flag_Y1_c As Integer '標(biāo)志位 Y1接通
Public flag_Y1_o As Integer
Public flag_Y2_c As Integer
Public flag_Y2_o As Integer
'''''''''''''''''''''''''''''''''''''
Dim receiveArr_shuzimokuai2() As Byte '下位機(jī)回傳數(shù)據(jù)
' CRC計(jì)算函數(shù)
Public Function CRC16(data() As Byte, crc() As Byte) As String
Dim CRC16Hi As Byte
Dim CRC16Lo As Byte
CRC16Hi = &HFF
CRC16Lo = &HFF
Dim i As Integer
Dim iIndex As Long
For i = 0 To 10 '不同情況下需修改數(shù)值,看具體回傳數(shù)據(jù)位數(shù)
iIndex = CRC16Lo Xor data(i)
CRC16Lo = CRC16Hi Xor GetCRCLo(iIndex)
CRC16Hi = GetCRCHi(iIndex)
Next i
crc(0) = CRC16Hi
crc(1) = CRC16Lo
End Function
'''''''''''''''''''''''''''''''''
'CRC低位字節(jié)值表
Public Function GetCRCLo(Ind As Long) As Byte
GetCRCLo = Choose(Ind + 1, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, _
&H81, &H40, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, _
&HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, _
&H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, _
&H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, _
&H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, _
&H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, _
&H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, _
&H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, _
&H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, _
&H81, &H40, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0, _
&HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, _
&HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H1, _
&HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40)
End Function
'''''''''''''''''''''''''''''''''''
'CRC高位字節(jié)值表
Public Function GetCRCHi(Ind As Long) As Byte
GetCRCHi = Choose(Ind + 1, &H0, &HC0, &HC1, &H1, &HC3, &H3, &H2, &HC2, &HC6, &H6, &H7, &HC7, &H5, &HC5, &HC4, &H4, _
&HCC, &HC, &HD, &HCD, &HF, &HCF, &HCE, &HE, &HA, &HCA, &HCB, &HB, &HC9, &H9, &H8, &HC8, &HD8, &H18, &H19, &HD9, &H1B, &HDB, &HAD, _
&H1A, &H1E, &HDE, &HDF, &H1F, &HDD, &H1D, &H1C, &HDC, &H14, &HD4, &HD5, &H15, &HD7, &H17, &H16, &HD6, &HD2, &H12, &H13, &HD3, &H11, _
&HD1, &HD0, &H10, &HF0, &H30, &H31, &HF1, &H33, &HF3, &HF2, &H32, &H36, &HF6, &HF7, &H37, &HF5, &H35, &H34, &HF4, &H3C, &HFC, &HFD, _
&H3D, &HFF, &H3F, &H3E, &HFE, &HFA, &H3A, &H3B, &HFB, &H39, &HF9, &HF8, &H38, &H28, &HE8, &HE9, &H29, &HEB, &H2B, &H2A, &HEA, &HEE, _
&H2E, &H2F, &HEF, &H2D, &HED, &HEC, &H2C, &HE4, &H24, &H25, &HE5, &H27, &HE7, &HE6, &H26, &H22, &HE2, &HE3, &H23, &HE1, &H21, &H20, &HE0, &HA0, &H60, _
&H61, &HA1, &H63, &HA3, &HA2, &H62, &H66, &HA6, &HA7, &H67, &HA5, &H65, &H64, &HA4, &H6C, &HAC, &HAD, &H6D, &HAF, &H6F, &H6E, &HAE, &HAA, &H6A, &H6B, _
&HAB, &H69, &HA9, &HA8, &H68, &H78, &HB8, &HB9, &H79, &HBB, &H7B, &H7A, &HBA, &HBE, &H7E, &H7F, &HBF, &H7D, &HBD, &HBC, &H7C, &HB4, &H74, &H75, &HB5, _
&H77, &HB7, &HB6, &H76, &H72, &HB2, &HB3, &H73, &HB1, &H71, &H70, &HB0, &H50, &H90, &H91, &H51, &H93, &H53, &H52, &H92, &H96, &H56, &H57, &H97, &H55, _
&H95, &H94, &H54, &H9C, &H5C, &H5D, &H9D, &H5F, &H9F, &H9E, &H5E, &H5A, &H9A, &H9B, &H5B, &H99, &H59, &H58, &H98, &H88, &H48, &H49, &H89, &H4B, &H8B, _
&H8A, &H4A, &H4E, &H8E, &H8F, &H4F, &H8D, &H4D, &H4C, &H8C, &H44, &H84, &H85, &H45, &H87, &H47, &H46, &H86, &H82, &H42, &H43, &H83, &H41, &H81, &H80, &H40)
End Function
'''''''''''''''''''''''''''''''''''
Private Sub cmd啟動(dòng)_Click() '命令按鈕
flag_Y1_c = 1
End Sub
Private Sub cmd停止_Click()
flag_Y2_c = 1
End Sub
''''''''''''''''''''''
Private Sub Form_Load()
lunxun_jishu = 0 '輪詢計(jì)數(shù)
' 以下數(shù)字模塊查詢字符 2號(hào)站
sendshuzimokuai2(0) = &H2 '查詢4個(gè)輸入口狀態(tài)
sendshuzimokuai2(1) = &H4
sendshuzimokuai2(2) = &H0
sendshuzimokuai2(3) = &H0
sendshuzimokuai2(4) = &H0
sendshuzimokuai2(5) = &H4
sendshuzimokuai2(6) = &HF1
sendshuzimokuai2(7) = &HFA
sendshuzimokuai2_Y1_c(0) = &H2 'Y1接通
sendshuzimokuai2_Y1_c(1) = &H6
sendshuzimokuai2_Y1_c(2) = &H0
sendshuzimokuai2_Y1_c(3) = &H0
sendshuzimokuai2_Y1_c(4) = &H0
sendshuzimokuai2_Y1_c(5) = &H1
sendshuzimokuai2_Y1_c(6) = &H48
sendshuzimokuai2_Y1_c(7) = &H39
sendshuzimokuai2_Y1_o(0) = &H2 'Y1斷開
sendshuzimokuai2_Y1_o(1) = &H6
sendshuzimokuai2_Y1_o(2) = &H0
sendshuzimokuai2_Y1_o(3) = &H0
sendshuzimokuai2_Y1_o(4) = &H0
sendshuzimokuai2_Y1_o(5) = &H0
sendshuzimokuai2_Y1_o(6) = &H89
sendshuzimokuai2_Y1_o(7) = &HF9
sendshuzimokuai2_Y2_c(0) = &H2 'Y2接通
sendshuzimokuai2_Y2_c(1) = &H6
sendshuzimokuai2_Y2_c(2) = &H0
sendshuzimokuai2_Y2_c(3) = &H1
sendshuzimokuai2_Y2_c(4) = &H0
sendshuzimokuai2_Y2_c(5) = &H1
sendshuzimokuai2_Y2_c(6) = &H19
sendshuzimokuai2_Y2_c(7) = &HF9
sendshuzimokuai2_Y2_o(0) = &H2 'Y2斷開
sendshuzimokuai2_Y2_o(1) = &H6
sendshuzimokuai2_Y2_o(2) = &H0
sendshuzimokuai2_Y2_o(3) = &H1
sendshuzimokuai2_Y2_o(4) = &H0
sendshuzimokuai2_Y2_o(5) = &H0
sendshuzimokuai2_Y2_o(6) = &HD8
sendshuzimokuai2_Y2_o(7) = &H39
Timer_lx.Enabled = True '一秒輪詢一次
Timer_lx.Interval = 1000
MSComm1.CommPort = 4 '設(shè)置Com4為通信端口
MSComm1.Settings = "4800,n,8,1"
MSComm1.InBufferSize = 128 '設(shè)置接收緩沖區(qū)128字節(jié)
MSComm1.OutBufferSize = 128 '設(shè)置發(fā)送緩沖區(qū)
MSComm1.InBufferCount = 0 '清空輸入緩沖區(qū)
MSComm1.OutBufferCount = 0 '清空輸出緩沖區(qū)
MSComm1.SThreshold = 1 '發(fā)送緩沖區(qū)空觸發(fā)發(fā)送事件 代表發(fā)送完畢
MSComm1.InputMode = comInputModeBinary '二進(jìn)制
MSComm1.PortOpen = True
End Sub
'''''''''''''''''''''''''''''''''''''''
Private Sub Timer_lx_Timer()
lunxun_jishu = lunxun_jishu + 1 '計(jì)數(shù)正確,這樣1秒輪巡一次 最快
If lunxun_jishu = 1 Then
MSComm1.RThreshold = 13 '回傳數(shù)據(jù)13位,每13個(gè)字符到接收緩沖區(qū)引起觸發(fā)接收事件
Receiveover_shuzimokuai2 = False '先否定
MSComm1.OutBufferCount = 0 '清空輸出緩沖區(qū)
MSComm1.InBufferCount = 0 '清空輸入緩沖區(qū)
MSComm1.Output = sendshuzimokuai2 '發(fā)送 查詢作用
End If
If lunxun_jishu = 2 Then '分析數(shù)據(jù)
If (Receiveover_shuzimokuai2 = False) Then
txt_lunxun1 = "數(shù)字通訊失敗" '沒有收到回傳數(shù)據(jù)
End If
If (Receiveover_shuzimokuai2 = True) Then
txt_lunxun1 = "數(shù)字通訊正常"
End If
If flag_Y1_c = 1 Then '啟動(dòng)按鈕按下
MSComm1.OutBufferCount = 0 '清空輸出緩沖區(qū)
MSComm1.Output = sendshuzimokuai2_Y1_c 'Y1接通
End If
If flag_Y2_c = 1 Then '停止按鈕按下
MSComm1.OutBufferCount = 0 '清空輸出緩沖區(qū)
MSComm1.Output = sendshuzimokuai2_Y2_c 'Y2接通
End If
End If
If lunxun_jishu = 3 Then
If flag_Y1_c = 1 Then
MSComm1.OutBufferCount = 0 '清空輸出緩沖區(qū)
MSComm1.Output = sendshuzimokuai2_Y1_o 'Y1斷開 相當(dāng)于松開啟動(dòng)按鈕,不能保持接通,因?yàn)榻佑|器會(huì)自鎖
flag_Y1_c = 0 '按鈕命令復(fù)位
End If
If flag_Y2_c = 1 Then
MSComm1.OutBufferCount = 0 '清空輸出緩沖區(qū)
MSComm1.Output = sendshuzimokuai2_Y2_o 'Y2斷開,常閉點(diǎn)閉合,為下一次啟動(dòng)準(zhǔn)備
flag_Y2_c = 0 '按鈕命令復(fù)位
End If
End If
If lunxun_jishu = 4 Then
lunxun_jishu = 0
End If
End Sub
''''''''''''''''''''''''''''''''''''''''
Private Sub hexReceive()
If (MSComm1.InBufferCount = 13) Then '數(shù)據(jù)回傳了
receiveArr_shuzimokuai2 = MSComm1.Input
Dim crcc(1) As Byte '用于CRC校驗(yàn)
Dim jisuandedao(1) As Byte '計(jì)算得到
Dim ret As String
Dim yanzheng(11) As Byte '取前11位
yanzheng(0) = receiveArr_shuzimokuai2(0)
yanzheng(1) = receiveArr_shuzimokuai2(1)
yanzheng(2) = receiveArr_shuzimokuai2(2)
yanzheng(3) = receiveArr_shuzimokuai2(3)
yanzheng(4) = receiveArr_shuzimokuai2(4)
yanzheng(5) = receiveArr_shuzimokuai2(5)
yanzheng(6) = receiveArr_shuzimokuai2(6)
yanzheng(7) = receiveArr_shuzimokuai2(7)
yanzheng(8) = receiveArr_shuzimokuai2(8)
yanzheng(9) = receiveArr_shuzimokuai2(9)
yanzheng(10) = receiveArr_shuzimokuai2(10)
ret = CRC16(yanzheng, crcc()) '計(jì)算校驗(yàn)碼函數(shù)
jisuandedao(0) = crcc(1) '得到兩位校驗(yàn)碼
jisuandedao(1) = crcc(0)
'如果計(jì)算得到的校驗(yàn)碼與回傳的校驗(yàn)碼一致,shape顏色改變
If (jisuandedao(0) = receiveArr_shuzimokuai2(11)) And (jisuandedao(1) = receiveArr_shuzimokuai2(12)) Then
Shape_yanzheng.FillColor = RGB(255, 123, 0)
End If
MSComm1.InBufferCount = 0 '清空輸入緩沖區(qū)
If receiveArr_shuzimokuai2(0) = &H2 Then '地址站號(hào)2
Receiveover_shuzimokuai2 = True
If (receiveArr_shuzimokuai2(4) = &H1) Then 'X1接通,代表接觸器吸合
Shape_run.FillColor = RGB(255, 0, 0) '運(yùn)行小紅燈紅色,代表運(yùn)行
Else
Shape_run.FillColor = RGB(255, 255, 255)
End If
End If
End If
End Sub
''''''''''''''''''''''''''''''''''''''''''
Private Sub MSComm1_OnComm()
Select Case MSComm1.CommEvent '
Case comEvReceive '接收事件 接收到?個(gè)字符,產(chǎn)生事件
Call hexReceive '去處理接收到的數(shù)據(jù)
Case comEvSend '發(fā)送事件 發(fā)送緩沖區(qū)空,發(fā)生事件 重要*,對(duì)應(yīng)屬性
' Sendover = True '發(fā)送完畢
End Select
End Sub
|
|