接触vb的串口控件也有一段时间了
经常被它弄得晕头转向
最重要的是死机 死机 死机
其實關鍵在於 寫好接收函數
现将自己的经验写下来供大家参考
1,使用串口
(1)臺式機自帶串口
(2)USB——– RS232(RS485)
(3)PCI —-RS232
適合一般對串口數需求小的通信
適合筆記本使用或串口不夠用外擴
適合工控使用(現正在使用的8口串口)
2,注意事項:上電,中斷,協議
1,下位機中單片機控制的232晶片,在上電後會自動發送FF FEFC 00 01 03等隨機通信數據給電腦串口 ,如果不處理好,在上電時就會出現數據異常或通信錯誤
2,vb編程時儘量不要使定時器和串口中斷會同時發生的情況出現
3,通信中儘量使用協議,自定義的協議或標準協議,例如接收超時的規定
3,編程
Vb中對串口的操作無非就是
設置串口屬性,讀取串口屬性,,讀取串口數據,發送數據
流程為:設置埠號—設置通信模式,串列傳輸速率,閥值等—清空緩衝區數據—-打開串口
下麵一一介紹
讀取,設置串口屬性
屬性
說明
(Name)
MSComm控制項的名稱
(自定義)
打開屬性頁
CommPort
獲得或設置通訊埠號
DTREnable
決定在通訊過程中是否使資料終端機狀態線有效。取值為:TrueFalse
EOFEnable
獲得或設置是否搜索EOF字元。取值為:TrueFalse
Handshaking
獲得或設置軟體的握手協定。取值為:0 comNone1 comXOnXoff2 comRTS3 comRTSXOnXOff
InBufferSize
獲得或設置接收緩衝區的大小,以位元組數為單位。
Index
在物件陣列中的編號
InputLen
獲得或設置輸入屬性從接收緩衝區讀出的字元數。
InputMode
獲得或設置輸入屬性檢索的資料類型。取值為:0 comInputModeText1 comInputModeBinary
Left
距離容器左邊框的距離
NullDiscard
決定是否將空字串從埠傳送到接收緩衝區。取值為:TrueFalse
OutBufferSize
獲得或設置傳輸緩衝區中的字元數
ParityReplace
獲得或設置當出現奇偶校驗錯誤時,用來替換資料流程中無效字元的字元。
RThreshold
獲得或設置要接受的字元數。
RTSEnable
決定能否使行有效。取值為:TrueFalse
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
接收函數
Private Sub MSComm1_OnComm()
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
带上心灵去旅行,以平和的心态看待一切,