mscomm1串口发送接收数据不正确
各位大虾好,我想问一个问题,我在编写一个上位机的程序,碰到了一些问题,具体是这样的,单片机每隔0.5秒向上位机发送一个FAH,如果上位机发送回AAH,那么就可以收到一串数据串,格式是这样的00H(或者01H,00H表示未启动,01H表示单片机启动工作),00H(“时间”的高位),XXH(“时间”的低位,),00H(“阻抗”的高位),YYH(“阻抗”的低位),ZZH(“温度”的整数部分),RRH(“温度”的小数
部分),SSH(“功率”的整数部分),TTH(“功率”的整数部分)。等于是接收到00h,00h,xxh,00h,yyh,zzh,rrh,ssh,tth共9字节内容,我现在编程写了一段代码,但是接收到的数据不太正确,代码如下:
发送部分:
Private Sub Timer1_Timer() '发送数据
Dim aa(0) As Byte '定义动态数组
If Not MSComm1.PortOpen Then
MSComm1.PortOpen = True '打开串行口
End If
aa(0) = &HAA '地址
MSComm1.OutBufferCount = 0 '清空输出寄存器
MSComm1.Output = aa '发送
End Sub
接收部分:
Private Sub MSComm1_OnComm()
Dim ab(11) As Byte
On Error Resume Next
With MSComm1
Select Case .CommEvent
Case comEvReceive '是接收事件
av = .Input '读取一个字节
ab(1) = av(0) '转换字节数据类型数组
If ab(1) = FAH Then '判断是否为数据开始标志
RThreshold = 0 '关闭OnComm事件接收
Do
DoEvents
Loop Until .InBufferCount > = 11
av = .Input
ab(2) = av(0)
av = .Input
ab(3) = av(0)
av = .Input
ab(4) = av(0)
av = .Input
ab(5) = av(0)
av = .Input
ab(6) = av(0)
av = .Input
ab(7) = av(0)
av = .Input
ab(8) = av(0)
av = .Input
ab(9) = av(0)
av = .Input
ab(10) = av(0)
av = .Input
ab(11) = av(0)
Label1 = ab(2)
Label2 = ab(3)
Label3 = ab(4)
Label4 = ab(5)
Label5 = ab(6)
Label6 = ab(7)
Label7 = ab(8)
Label8 = ab(9)
Label9 = ab(10)
Label10 = ab(11)
.RThreshold = 1
End If
Case Else
End Select
End With
End Sub
Private Sub Form_Load()
With MSComm1
.CommPort = 1 '使用COM1
.Settings = "4800,N,8,1 " '设置通信口参数
.OutBufferSize = 1 '设置发送缓冲区为1 字节
.InputMode = comInputModeBinary '设置接收数据模式为二进制形式
.InputLen = 1 '设置Input 一次从接收缓冲读取字节数为1
.SThreshold = 1 '设置Output 一次从发送缓冲读取字节数为1
.InBufferCount = 0 '清除接收缓冲区
.OutBufferCount = 0 '清除发送缓冲区
.RThreshold = 1 '设置接收一个字节产生OnComm事件
If .PortOpen = False Then '判断通信口是否打开
.PortOpen = True '打开通信口
If Err Then '错误处理
MsgBox "串口通信无效 "
Exit Sub
End If
End If
End With
End Sub
已知未启动时接收到的“时间”为60秒,阻抗是100,温度是25,那么未启动时正常接收到的数据应该是label1=0 label2=0 label3=60 label4=0 label5=100 label6=0 label7=0 label8=0 label9=0 label10=250 label11=250(为什么?)
但是实际上接收到的数据是正确的,但却在各个label上乱跳,比如label1有时是0有时是60有时是100,有时是250,其他label也一样。
启动后除了多一个1外情况差不多,我想问下这是怎么回事,另外我的定时器timer设为500ms,这种情况还能不能用其他编程方法来实现,不要用我这种代码?请大虾们帮帮我吧。
谢谢了!!
[解决办法]
http://community.csdn.net/Expert/topic/5366/5366904.xml?temp=9.821719E-02
请参阅上述网址2007-2-28 14:17:23 本人的答复,该代码是以二进制接收下位机命令的.建议将MSCOMM的属性RThreshold设置为9,且在
'此处添加处理接收的代码
行后的Call GetDisplayText句后添加你需判别接收的代码.
另请参阅如下代码:
Private Sub ctrMSComm_OnComm()
Dim bytInput() As Byte
Dim intInputLen As Integer
Dim outputV As Single
Select Case frmMain.ctrMSComm.CommEvent
Case comEvReceive
If blnReceiveFlag Then
If Not frmMain.ctrMSComm.PortOpen Then
frmMain.ctrMSComm.CommPort = intPort
frmMain.ctrMSComm.Settings = strSet
frmMain.ctrMSComm.PortOpen = True
End If
'此处添加处理接收的代码
frmMain.ctrMSComm.InputMode = comInputModeBinary
intInputLen = frmMain.ctrMSComm.InBufferCount
Text3 = intInputLen
ReDim bytInput(intInputLen)
bytInput = frmMain.ctrMSComm.Input
Call InputManage(bytInput, intInputLen)
Call GetDisplayText
'插入处理代码
Text2 = HexStr1
If Mid(HexStr1, 17, 2) > = 80 And Mid(HexStr1, 17, 2) <= 81 Then
If Mid(HexStr1, 17, 2) = "80 " Then
blL = Mid(HexStr1, 11, 2)
Call Hex_bin '判别故障
alame(0) = Mid(zt_dm1, 2.1)
dizhi = Val(Mid(HexStr1, 18, 1))
xh = Val(Mid(HexStr1, 20, 1))
outputV = Val( "&H " & Mid(HexStr1, 9, 2)) / 2.55
frmYibiao.Label2(dizhi) = Int(outputV)
sj_bm(dizhi, xh) = Val( "&H " & Mid(HexStr1, 5, 4)) / 10 '16进制转换为10进制
frmYibiao.Label1(dizhi) = sj_bm(dizhi, xh)
record_jm(0) = Val( "&H " & Mid(HexStr1, 1, 4)) / 10
frmYibiao.Label3(dizhi) = record_jm(0) 'Val( "&H " & Mid(HexStr1, 5, 4)) / 10
If xh = 2 Then
End If
ElseIf Mid(HexStr1, 17, 2) = "81 " Then
blL = Mid(HexStr1, 11, 2)
Call Hex_bin '判别故障
alame(1) = Mid(zt_dm1, 2.1)
dizhi = Val(Mid(HexStr1, 18, 1))
xh = Val(Mid(HexStr1, 20, 1))
outputV = Val( "&H " & Mid(HexStr1, 9, 2)) / 2.55
frmYibiao.Label2(dizhi) = Int(outputV)
sj_bm(dizhi, xh) = Val( "&H " & Mid(HexStr1, 5, 4)) / 10
frmYibiao.Label1(dizhi) = sj_bm(dizhi, xh)
record_jm(1) = Val( "&H " & Mid(HexStr1, 1, 4)) / 10
frmYibiao.Label3(dizhi) = record_jm(1) 'Val( "&H " & Mid(HexStr1, 5, 4)) / 10
If xh = 2 Then
End If
End If
Text4 = Val(jieshou_sj) / 10
Text5 = Mid(HexStr1, 17, 2) & Mid(HexStr1, 19, 2) & Text4
End If
Call display
If Val(Text3) > = 10 Then
Call cmdClear_Click
End If
If Not blnAutoSendFlag And Not blnReceiveFlag Then
frmMain.ctrMSComm.PortOpen = False
End If
End If
End Select
End Sub
注意以下语句的用法,接收10字节清0用:
If Val(Text3) > = 10 Then
Call cmdClear_Click
End If
祝好运.
[解决办法]
每次comEvReceive发生一次(当接收到一个数据时),所有的LABEL控件会得到一个数据,所以会出现循环赋值的错误。
由于接收的数据长度固定,建议将RThreshold设置为9。这样一次即可处理完获得的数据,显示也不会错误。
[解决办法]
帮顶