VB 串列埠程式設計 開發心得
1,使用串列埠 |
(1)桌上型電腦自帶串列埠 |
(2)USB-------- RS232(RS485) |
(3)PCI ----RS232 |
||
適合一般對串列埠數需求小的通訊 |
適合筆記本使用或串列埠不夠用外擴 |
適合工控使用(現正在使用的8口串列埠) |
2,注意事項:上電,中斷,協議 |
1,下位機中微控制器控制的232晶片,在上電後會自動傳送FF FE FC 00 01 03等隨機通訊資料給電腦串列埠 ,如果不處理好,在上電時就會出現資料異常或通訊錯誤
2,vb程式設計時儘量不要使定時器和串列埠中斷會同時發生的情況出現
3,通訊中儘量使用協議,自定義的協議或標準協議,例如接收超時的規定
3,程式設計 |
Vb中對串列埠的操作無非就是
設定串列埠屬性,讀取串列埠屬性,讀取串列埠資料,傳送資料
流程為:設定埠號—設定通訊模式,串列傳輸速率,閥值等---清空緩衝區資料----開啟串列埠
下麵一一介紹
讀取,設定串列埠屬性
屬性 |
說明 |
(Name) |
MSComm控制項的名稱 |
(自定義) |
開啟屬性頁 |
CommPort |
獲得或設定通訊埠號 |
DTREnable |
決定在通訊過程中是否使資料終端機狀態線有效。取值為: |
EOFEnable |
獲得或設定是否搜尋EOF字元。取值為: |
Handshaking |
獲得或設定軟體的握手協定。取值為: |
InBufferSize |
獲得或設定接收緩衝區的大小,以位元組數為單位。 |
Index |
在物件陣列中的編號 |
InputLen |
獲得或設定輸入屬性從接收緩衝區讀出的字元數。 |
InputMode |
獲得或設定輸入屬性檢索的資料型別。取值為: |
Left |
距離容器左邊框的距離 |
NullDiscard |
決定是否將空字串從埠傳送到接收緩衝區。取值為: |
OutBufferSize |
獲得或設定傳輸緩衝區中的字元數 |
ParityReplace |
獲得或設定當出現奇偶校驗錯誤時,用來替換資料流程中無效字元的字元。 |
RThreshold |
獲得或設定要接受的字元數。 |
RTSEnable |
決定能否使行有效。取值為: |
Settings |
獲得或設定串列傳輸速率、奇偶校驗、資料位元和停止位元引數。 |
SThreshold |
獲得或設定傳輸中所能允許的最小字元數 |
Tag |
儲存程式所需的附加資料 |
Top |
距容器頂部邊界的距離 |
設定串列埠:
PrivateFunction com1_init(com_no As Byte)
OnError GoTo err
IfMSComm1.PortOpen = True Then MSComm1.PortOpen = False
MSComm1.CommPort= com_no
IfMSComm1.PortOpen = False Then
MSComm1.Settings ="9600,n,8,1"
MSComm1.RThreshold = 1 '******核心語句,去掉則無法觸發,來一個位元組資料就中斷
'MSComm1.SThreshold = 1 '傳送緩衝區中允許的最小字元數觸發
MSComm1.OutBufferSize = 10 ‘傳送緩衝區大小位元組
MSComm1.InBufferSize = 10 ‘傳送緩衝區大小位元組
MSComm1.InputLen = 1 '每次從緩衝區讀取資料的位元組數
MSComm1.InputMode =comInputModeBinary '二進位制模式
'MSComm1.InputMode =comInputModeText ‘文字模式
MSComm1.InBufferCount = 0 '清空接收緩衝區資料
MSComm1.PortOpen = True '開啟串列埠
EndIf
ExitFunction
err:
MsgBox"串列埠開啟失敗"
EndFunction
接收,傳送資料
(1) 兩種模式下的資料收發
1------------------------------二進位制模式:以二進位制模式收發,比如傳送0XFE 注:傳送時使用陣列傳送
MSComm1.InputMode= comInputModeBinary '二進位制模式
傳送資料函式
Dim cc(0) As Byte
cc(0) = mydata
MSComm1.Output = cc
接收資料函式(接收一個位元組的資料,也就是說來的數只有8位)
MSComm1.InputLen= 1 每次從緩衝區讀出來1個數(8位為一個,也可以自己定義接收多個)
Private Sub MSComm1_OnComm()
Dim Instring As Byte
On Error GoTo err
Select Case MSComm3.CommEvent
CasecomEvReceive
DimInByte, i As Integer
InByte = MSComm3.Input
Fori = 0 To UBound(InByte)
Instring = Instring & (InByte(i))
Next
End Select
End Sub
接收函式(一次接收多個位元組的這樣寫)
MSComm1.InputLen= 0 每次從緩衝區讀出來所有資料
Dim counter As Byte
counter = MSComm1.InBufferCount
If counter > 0 Then
DimReceiveArr() As Byte
Dimj, Instring As Integer
ReceiveArr = MSComm1.Input ‘把得到的資料放在一個陣列中
Forj = 0 To (counter - 1)
Instring = ReceiveArr(j) ‘迴圈檢視得到的每一個數
IfVal(Instring) = 1 Then Text1.Text = Text1.Text + "ok "
Nextj
Else
End If
2------------------------文字模式:傳送和接收的都是ascii形式的字串,比如我可以傳送’S’給output
'MSComm1.InputMode= comInputModeText ‘文字模式
MSComm1.InputLen= 0 每次接收緩衝區的所有字串
傳送函式dim outstring as string MSComm1.Input= outstring
接收函式
Dim Instring ‘也可以定義成string型別
On Error GoTo err
Select Case MSComm1.CommEvent
Case comEvReceive
Instring = MSComm1.Input
End Select
err:
End Sub
(2) 接收資料的方法(重要)
1中斷 |
2查詢(1) |
3查詢(2) |
4中斷+查詢 |
MSComm1.RThreshold =n 來n個數馬上產生中斷 |
MSComm1.RThreshold = 0 關閉中斷觸發 |
MSComm1.RThreshold = 0 關閉中斷觸發 |
MSComm1.RThreshold = n 來n個數馬上產生中斷 |
在中斷函式中讀取接收到的資料 Private Sub MSComm1_OnComm() 你的程式碼 End Sub |
使用定時器,每隔10ms或其他時間段,就查詢是否接收到資料了,沒有則退出,有則讀取資料 Dim counter As Byte counter = MSComm1.InBufferCount |
適合超時檢測用 先傳送 延時 檢測是否接收到了 Dim counter As Byte counter = MSComm1.InBufferCount |
在中斷發生時,在中斷函式中,延時或使用其他方法進行查詢 |
4,特殊通訊 |
大於255的數,小數,modbus通訊,回車換行
大於255的數
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias"RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length AsLong)
Private Sub Form_Load()
MSComm1.Settings = "9600,n,8,1"
MSComm1.PortOpen = True
Text1 = 256
End Sub
Private Sub Command1_Click()
Dim a As Integer
a = Val(Text1)
Dim buffer(1) As Byte
CopyMemory buffer(0), a, 2 '獲得Byte陣列,低位元組在前,高位元組在後
MSComm1.Output = buffer
End Sub
小數
用多位資料來表示
modbus通訊
起始位停止位 奇數偶數校驗都可以設定
Crc程式程式碼
Dim CRC_HiByte As Byte,CRC_LowByte As Byte
Private FunctionCRC16(ByRef cmdstring() As Byte, ByVal j As Integer)
Dim data As Integer
Dim I As Integer
Addressreg_crc = &HFFFF
For I = 0 To j
Addressreg_crc = Addressreg_crcXor cmdstring(I)
For j = 0 To 7
data = Addressreg_crcAnd &H1
If data Then
Addressreg_crc= Int(Addressreg_crc / 2)
Addressreg_crc= Addressreg_crc And &H7FFF
Addressreg_crc= Addressreg_crc Xor &HA001
Else
Addressreg_crc= Addressreg_crc / 2
Addressreg_crc= Addressreg_crc And &H7FFF
End If
Next j
Next I
If Addressreg_crc < 0 Then
Addressreg_crc = Addressreg_crc -&HFFFF0000
End If
CRC_HiByte = Addressreg_crc And&HFF
CRC_LowByte = (Addressreg_crc And&HFF00) / &H100
End Function
Private SubCommand1_Click()
Dim mydat(2) As Byte
mydat(0) = &H1
mydat(1) = &HF0
Call CRC16(mydat(), 2)
Text1.Text =Hex(CRC_HiByte)
Text2.Text =Hex(CRC_LowByte)
MsgBox " changok!!"
End Sub
回車vbcr
回車換行vbcrlf
5,程式設計細節(技巧) |