学习MSComm又遇问题!

wumylove1234 2004-09-19 09:20:10
Option Explicit

Private Sub Command1_Click()
On Error GoTo ErrHandle:
If MSComm1.PortOpen = False Then
Me.MSComm1.CommPort = CInt(Text2.Text)
MSComm1.Settings = Text3.Text & "," & Text4.Text & "," & Text5.Text & "," & Text6.Text
MSComm1.RThreshold = 1
MSComm1.PortOpen = True
Command1.Caption = "关闭端口"
ElseIf MSComm1.PortOpen = True Then
MSComm1.PortOpen = False
Command1.Caption = "打开端口"
End If
Exit Sub
ErrHandle:
MsgBox Err.Number & ":" & Err.Description
End Sub

Private Sub MSComm1_OnComm()
MSComm1.InputMode = comInputModeBinary
Select Case MSComm1.CommEvent
Case comEvReceive
Dim intLength As Integer
intLength = 0
Dim myArray() As Byte
intLength = MSComm1.InBufferCount
ReDim myArray(intLength)
myArray = MSComm1.Input
Text1.Text = ConvertToString(myArray)

End Select

End Sub

Private Function ConvertToString(inputArray() As Byte) As String
Dim strHex As String
Dim strString As String
Dim i As Integer
For i = 0 To UBound(inputArray)
strHex = strHex & CStr(Hex(inputArray(i))) & " "
If inputArray(i) < 32 Or inputArray(i) > 128 Then
strString = strString & Chr(63)
Else
strString = strString & Chr(inputArray(i))
End If
Next
ConvertToString = strHex & vbCr & strString & vbCr
End Function

这是我的测试代码,我发现单步调试时结果正常,直接运行就只接给我显示了strHex和strString最后两个字符,我读出来的数据是D ?,D是strHex的最后一位,?是strString的最后一位,但我单步调试是一样的.还有,我发现,如果我把断点放在ConvertoString这过程中会是这个结果,如果把断点放在OnComm事件里,结果是正常的,这是为什么啊?
我参考了串口调试工具的源码,它的确不会出问题,难道是它的单码长,我的代码短?
...全文
167 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
wumylove1234 2004-09-20
  • 打赏
  • 举报
回复
Wenking003(文君)
你的方法可以了,呵呵,谢谢你.

忙烦你再帮我看看用变量保存的方法.

还有,就是用Text的话,我也是一样不知道什么时候应该清掉文本框内的值,你说对吗?如何确定输卡结束呢!

我在想,我这个卡里,一共是12个字节,前10位是数字,可以正常的转化为ASCII码,进而转化为字符,后两位具体我还没有看,会是什么?有一位是停止位吗?
我想应该是的,那请问,其它的一类,比如考勤机一类的,都会有像这张卡似的结束位吗?
wumylove1234 2004-09-20
  • 打赏
  • 举报
回复
好的,我试试.
不过我现在做了这样的修改:
Dim DataInput() As Byte
Private Sub Command1_Click()
On Error GoTo ErrHandle:
If MSComm1.PortOpen = False Then
Me.MSComm1.CommPort = CInt(Text2.Text)
MSComm1.Settings = Text3.Text & "," & Text4.Text & "," & Text5.Text & "," & Text6.Text
MSComm1.RThreshold = 1
MSComm1.PortOpen = True
Command1.Caption = "关闭端口"
ElseIf MSComm1.PortOpen = True Then
MSComm1.PortOpen = False
Command1.Caption = "打开端口"
End If
Exit Sub
ErrHandle:
MsgBox Err.Number & ":" & Err.Description
End Sub

Private Sub Command2_Click()
ReDim DataInput(0)
End Sub

Private Sub Form_Load()
ReDim DataInput(0)
MSComm1.InputLen = 0
End Sub

Private Sub MSComm1_OnComm()
'Delay 2
MSComm1.InputMode = comInputModeBinary
Select Case MSComm1.CommEvent
Case comEvReceive
Dim intLength As Integer
intLength = 0
Dim myArray() As Byte
intLength = MSComm1.InBufferCount
ReDim myArray(intLength)
myArray = MSComm1.Input
Call BufferInput(myArray, intLength)
Text1.Text = ConvertToString()
End Select

End Sub
Private Sub BufferInput(allArray() As Byte, DataLength As Integer)
Dim i As Integer
i = UBound(DataInput)
ReDim Preserve DataInput(i + DataLength)
Dim j As Integer
For j = 0 To DataLength - 1
DataInput(i + j) = allArray(j)
Debug.Print Chr(allArray(j))
Next
End Sub
Private Function ConvertToString() As String
Dim strHex As String
Dim strString As String
Dim i As Integer
For i = 0 To UBound(DataInput) - 1
strHex = strHex & CStr(Hex(DataInput(i))) & " "
If DataInput(i) < 32 Or DataInput(i) > 128 Then
strString = strString & Chr(63)
Else
strString = strString & Chr(DataInput(i))
End If
Next
ConvertToString = strHex & vbCr & strString & vbCr
End Function我现在又用一个窗体级变量,保存接收的值,不过现在还有问题,我如何确定在正确接收完一次数据后,清掉窗体级变量DataInput呢?现在的是它永远都在不断的增长,我上边中放了一个按钮来清它的内容~因为无法确定什么时候才接收完一次刷卡的内容!
Wenking003 2004-09-20
  • 打赏
  • 举报
回复
这也是很明显的发送-接收”不同步的现象:
因为发送与接收不同步,变成了你是“分段”接收到信息的,但你在程序中采用了:
Text1.Text = ConvertToString(myArray),每次新接收到的数据把旧的数据都抹掉了。
当你单步跟踪,或把断点设在OnComm事件里,结果是正常的,是因为程序的停顿能让PC把数据全部接收后再去处理。
建议:Text1.Text = Text1.Text & ConvertToString(myArray)
wumylove1234 2004-09-20
  • 打赏
  • 举报
回复
我晕~不是真的吧.

没有人理我啊~
wumylove1234 2004-09-20
  • 打赏
  • 举报
回复
现在已经得到数据了.而且因为它有结束位,我猜是结束位吧.我没有这个读卡器的任何资料.
数据后面有两位,一个A,一个D,我就判断那个D吧.反正现在测试是正常的!

大概知道是怎么回事了.现在也没有工作,更涉及不到这方面的项目,只是学习测试,现在收数据可以了,发数据没有这样的设备,暂时告一段落!:(

谢谢各位!
叶帆 2004-09-20
  • 打赏
  • 举报
回复
请参考:
http://community.csdn.net/Expert/topic/3387/3387736.xml?temp=.8557855

我一般不喜欢用OnComm触发事件,除非万不得已!
ajianchen2002 2004-09-20
  • 打赏
  • 举报
回复
关注
小弟也初学VB串口通讯编程
多多指教
Wenking003 2004-09-20
  • 打赏
  • 举报
回复
对于你的情况,由于两次读卡之间会有明显的时间段,因此你可以在MSComm1_OnComm()中进行一个时间的控制,如0.5秒内接收到的信息是属于最近一次刷卡的信息,超过这个时间段就属于其它的信息,这样你就可以清楚地知道你什么时候处理完一张卡,什么时候该清掉文本框内的值。
至于是否有停止位什么的,各读写器都不同,这要靠你自己去摸索了。
lsftest 2004-09-20
  • 打赏
  • 举报
回复
留言收到。。。
关键是看你连接的外设定的通讯协议是怎么样的。。。一般来说你买读卡器、考勤机的时候都可以通过代理商得到厂家的通讯协议资料。。。如果没有,就只能自己慢慢摸索猜一下了。。。


还有,就是用Text的话,我也是一样不知道什么时候应该清掉文本框内的值,你说对吗?如何确定输卡结束呢!
===================
要看你的读卡器每次刷卡的时候传过来的是否定长数据和有没有始、停位,如果都有则比较简单,设置好mscomm一般就可以了。。。。
但如果是不定长或没有始、停位则很麻烦,只能自己写代码进行判断(根据接收到的数据和卡的属性(例如卡号)进行分析。。。说白了就是搞清楚它的通讯协议)。。。不定长数据的接收参考:
http://www.gjwtech.com/scomm/scvbprogramseveralques.htm
wumylove1234 2004-09-20
  • 打赏
  • 举报
回复

Dim str As String

Private Sub Command1_Click()
On Error GoTo ErrHandle:
If MSComm1.PortOpen = False Then
Me.MSComm1.CommPort = CInt(Text2.Text)
MSComm1.Settings = Text3.Text & "," & Text4.Text & "," & Text5.Text & "," & Text6.Text
MSComm1.RThreshold = 1
MSComm1.PortOpen = True
Command1.Caption = "关闭端口"
ElseIf MSComm1.PortOpen = True Then
MSComm1.PortOpen = False
Command1.Caption = "打开端口"
End If
Exit Sub
ErrHandle:
MsgBox Err.Number & ":" & Err.Description
End Sub

Private Sub MSComm1_OnComm()
MSComm1.InputMode = comInputModeBinary
Select Case MSComm1.CommEvent
Case comEvReceive
Dim intLength As Integer
intLength = 0
Dim myArray() As Byte
intLength = MSComm1.InBufferCount
ReDim myArray(intLength)
myArray = MSComm1.Input

str = str & ConvertToString(myArray)
Debug.Print str
If Right(str, 1) = "D" Then
Text1.Text = Left(str, 10)
str = ""
End If
End Select

End Sub

Private Function ConvertToString(inputArray() As Byte) As String
Dim strHex As String
Dim strString As String
Dim i As Integer
For i = 0 To UBound(inputArray)
'strHex = strHex & CStr(Hex(inputArray(i))) & " "
If inputArray(i) < 32 Or inputArray(i) > 128 Then
strString = strString & CStr(Hex(inputArray(i)))
Else
strString = strString & Chr(inputArray(i))
End If
Next
ConvertToString = strString
End Function

哈哈.终于实现了.

大侠帮我看看最后的这些代码,在实际应用中是否是正确的方法~我没有这方面的精验,比如说做考勤啊一类的东西的时候,大家都是如何用MSComm的?
Entire 2004-09-19
  • 打赏
  • 举报
回复
呵呵,我帮你解决了,现在来拿分,呵呵!
MysticBoys 2004-09-19
  • 打赏
  • 举报
回复
UP
wumylove1234 2004-09-19
  • 打赏
  • 举报
回复
现在看到问题,读一次卡,居然引发了四次的OnComm事件.
测试数据:
48
OK
48
49
48
51
51
OK
54
52
48
OK
55
10
13
OK

wumylove1234 2004-09-19
  • 打赏
  • 举报
回复
顶一下.没有人理我!

7,765

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧