mscomm控件一次只接收一个数据
想做一个毫秒级的监视串口软件,发现了几个不会的问题,请教大家一下.一.mscomm1.Rthreshold=1 一次也不只接一个数据
二.由mscomm1_oncomm事件中,毫秒级函数,会出现重复,例第一次比如,是500ms,第二次接收还有可能是500ms
我不会发附件,就直接贴代码了
Option Explicit
Private Declare Sub GetLocalTime Lib "kernel32" (lpSystemTime As SYSTEMTIME)
Private Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type
Public Function getdatetime() As String
Dim LCT As SYSTEMTIME
Dim ymd As String, hms As String
GetLocalTime LCT
ymd = Format(LCT.wYear & "-" & LCT.wMonth & "-" & LCT.wDay, "yyyy-MM-dd")
hms = Format(LCT.wHour, "00") & ":" & Format(LCT.wMinute, "00") & ":" & Format(LCT.wSecond, "00") & "." & Format(LCT.wMilliseconds, "000")
getdatetime = ymd & " " & hms
'MsgBox ymd & " " & hms
End Function
Private Sub cmdCom_Click()
'串口开/关
If MSComm1.PortOpen Then
Shape1.BackColor = vbBlack
MSComm1.PortOpen = False
Else
Shape1.BackColor = vbWhite
MSComm1.InBufferSize = 0
' MSComm1.InBufferSize = 2048
MSComm1.PortOpen = True
End If
End Sub
Private Sub cmdStart_Click()
'定时器开始
Timer1.Enabled = True
End Sub
Private Sub cmdStop_Click()
'定时器停止
Timer1.Enabled = False
End Sub
Private Sub MSComm1_OnComm()
Dim comT() As Byte
Dim sT As String
Dim i As Integer
Text1.Text = getdatetime
If MSComm1.CommEvent = comEvReceive Then
' MSComm1.RThreshold = 0 '防止在处理数据时产生OnComm事件
'Text1.Text = getdatetime
comT = MSComm1.Input
For i = 0 To UBound(comT)
sT = sT & DEC_to_HEX(CLng(comT(i))) & "--" & i & ","
'Debug.Print UBound(comT)
Next
List1.AddItem Text1.Text & "----" & sT
If List1.ListCount > 60 Then List1.Clear
'MSComm1.RThreshold = 1
End If
Debug.Print MSComm1.InBufferCount
End Sub
Public Function HEX_to_DEC(ByVal Hex As String) As Long
Dim i As Long
Dim B As Long
Hex = UCase(Hex)
For i = 1 To Len(Hex)
Select Case Mid(Hex, Len(Hex) - i + 1, 1)
Case "0": B = B + 16 ^ (i - 1) * 0
Case "1": B = B + 16 ^ (i - 1) * 1
Case "2": B = B + 16 ^ (i - 1) * 2
Case "3": B = B + 16 ^ (i - 1) * 3
Case "4": B = B + 16 ^ (i - 1) * 4
Case "5": B = B + 16 ^ (i - 1) * 5
Case "6": B = B + 16 ^ (i - 1) * 6
Case "7": B = B + 16 ^ (i - 1) * 7
Case "8": B = B + 16 ^ (i - 1) * 8
Case "9": B = B + 16 ^ (i - 1) * 9
Case "A": B = B + 16 ^ (i - 1) * 10
Case "B": B = B + 16 ^ (i - 1) * 11
Case "C": B = B + 16 ^ (i - 1) * 12
Case "D": B = B + 16 ^ (i - 1) * 13
Case "E": B = B + 16 ^ (i - 1) * 14
Case "F": B = B + 16 ^ (i - 1) * 15
End Select
Next i
HEX_to_DEC = B
End Function
Public Function DEC_to_HEX(Dec As Long) As String
Dim a As String
DEC_to_HEX = ""
If Dec = 0 Then DEC_to_HEX = "0": Exit Function
Do While Dec > 0
a = CStr(Dec Mod 16)
Select Case a
Case "10": a = "A"
Case "11": a = "B"
Case "12": a = "C"
Case "13": a = "D"
Case "14": a = "E"
Case "15": a = "F"
End Select
DEC_to_HEX = a & DEC_to_HEX
Dec = Dec \ 16
Loop
End Function
不好意思大家我真没几个分,请别见怪 --------------------编程问答-------------------- http://download.csdn.net/detail/veron_04/4037248 --------------------编程问答-------------------- 例子我看了,不是我想要的.我想实现,用毫秒真实的监测串口每一个数据,比如发送01 02 03 我想要的结果是
12:29:01 100 01
12:29:01 110 02
12:29:01 120 03
前面是毫秒数 后面是串口接收的一个数据 --------------------编程问答-------------------- 一.
mscomm1.Rthreshold = 1
mscomm1.InputLen = 1
二
用 QueryPerformanceCounter API 计时。Timer 精度太低。
--------------------编程问答-------------------- mscomm1.Rthreshold = 1
这样的设置也无法保证每次就读一个 --------------------编程问答-------------------- 用 timeGetTime 函数,为什么1毫秒接收两个字符,rthreshlod=1; inputlen=1 我是这么设置的 --------------------编程问答--------------------
这个设置的意思是,当接收到一个以上的字节时,OnComm 事件就会触发。
你可以用 mscomm1.InputLen = 1 来限定每一次用 Input 方法从串口缓存取回的数据是 1 字节。
你没有理解串口数据接收的实际过程。
真正的接收是硬件和驱动程序来完成的,会把接收到的数据放入 InBuffer。根据你所设置的 Rthreshold,驱动程序决定在收到几个字节后给你一个事件消息。
如果你设置 InputLen = 0,那么当你使用 Input 方法从 InBuffer 中提取数据时,当前有多少字节,就会统统给你。
实际上,你没有办法在不采用握手的协议下限制物理上实际接收的数据量的,那样可能会 Runover,也就是丢数据。你所说的接收几个字节,实际上是从已经接收好的数据中提取几个字节。
--------------------编程问答--------------------
这个太含蓄了。。我给楼主补充说明一下
第一个意思是mscomm1.Rthreshold = 1不能满足你的要求。这个属性意思是当缓存器有了大于1个数据就发送消息请求处理。
mscomm1.InputLen = 1 则表示一次取的长度。
取数据不就用的mscomm1.input 嘛。
补充:VB , 控件