当前位置:编程学习 > VB >>

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 我是这么设置的 --------------------编程问答--------------------
引用 4 楼  的回复:
mscomm1.Rthreshold = 1

这样的设置也无法保证每次就读一个


这个设置的意思是,当接收到一个以上的字节时,OnComm 事件就会触发。

你可以用 mscomm1.InputLen = 1 来限定每一次用 Input 方法从串口缓存取回的数据是 1 字节。

你没有理解串口数据接收的实际过程。

真正的接收是硬件和驱动程序来完成的,会把接收到的数据放入 InBuffer。根据你所设置的 Rthreshold,驱动程序决定在收到几个字节后给你一个事件消息。

如果你设置 InputLen = 0,那么当你使用 Input 方法从 InBuffer 中提取数据时,当前有多少字节,就会统统给你。

实际上,你没有办法在不采用握手的协议下限制物理上实际接收的数据量的,那样可能会 Runover,也就是丢数据。你所说的接收几个字节,实际上是从已经接收好的数据中提取几个字节。
--------------------编程问答--------------------
引用 3 楼  的回复:
一.
mscomm1.Rthreshold = 1
mscomm1.InputLen = 1


用 QueryPerformanceCounter API 计时。Timer 精度太低。

这个太含蓄了。。我给楼主补充说明一下
第一个意思是mscomm1.Rthreshold = 1不能满足你的要求。这个属性意思是当缓存器有了大于1个数据就发送消息请求处理。
mscomm1.InputLen = 1 则表示一次取的长度。
取数据不就用的mscomm1.input 嘛。
补充:VB ,  控件
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,