前两天受人之托写的一个程序,发上来共享,从中可以看到串口通信的常用处理方式,希望对大家有所帮助。
一、系统需求:使用三线制串口,利用vb与dsp通信,采集数据并存储为文本文件。
二、通信协议
1. RS232串行通信的波特率设为9600,8位数据位,一位停止位,无校验位。
2. 每组数据包含T1(16位)和T2(16位),将每个数据分成2个8位的数据,先是低8位,然后是高8位。数据为无符号整型。
先发T1,然后发T2,然后是下一组T1、T2。
T1以头数据0x0A(16进制,10进制位10)为头字节,然后是T1的低8位,T1的高8位。
T2以头数据0xA0(16进制,10进制位160)为头字节,然后是T2的低8位,T2的高8位。
发送时序举例:0x0A, t1低8位,t1高8位,0xA0, t2低8位,t2高8位……
将收到的数据T1、T2的高低8位合并,转换成10进制数,以每行T1 T2的形式存储到txt文本文件中。
三、要点说明
0. 如果通信协议没有考虑周全就着手开始做,可能会经受无比的痛苦
1. 文本框textbox的大小限制为32k,不符合大量数据的需要,因此使用richtextbox
2. 换行符为Chr(&HD) + Chr(&HA)
3. 需要用状态栏给出必要的信息
4. 保存文件的默认名字为当前日期
5. 收到comm事件后,需要关闭com事件接收,避免再次触发事件
四、程序源代码:
Dim av As Variant Dim datacount As Long Private Sub cmdClear_Click() txtData.Text = "" End Sub Private Sub cmdStop_Click() '关闭端口 If MSComm.PortOpen = True Then MSComm.InBufferCount = 0 '清空缓冲区 MSComm.PortOpen = False End If cmdReceive.Enabled = True lblStatus.Caption = "停止接收,空闲" End Sub Private Sub cmdReceive_Click() '串口设置 With MSComm .CommPort = 1 .Settings = "9600,N,8,1" .RThreshold = 1 '接收1字节触发oncomm事件 .InputMode = comInputModeBinary .InputLen = 1 '输入长度为1 .InBufferCount = 0 '清除接收缓冲区 End With '打开端口 If MSComm.PortOpen = False Then MSComm.PortOpen = True If Err Then MsgBox (Err.Description) Exit Sub End If End If lblStatus.Caption = "打开端口,等待接收" datacount = 0 cmdReceive.Enabled = False End Sub Private Sub cmdSave_Click() Dim outfn As String MsgBox ("接收了" + CStr(datacount) + "组数据") lblStatus.Caption = "接收完成,请选择输出文件" cmdReceive.Enabled = True '选择输出文件 CommonDialog1.FileName = CStr(Date) + ".txt" CommonDialog1.Filter = "Text Files|*.txt" CommonDialog1.Flags = CommonDialog1.Flags Or cdlOFNOverwritePrompt CommonDialog1.CancelError = True On Error GoTo errhandler CommonDialog1.ShowSave outfn = CommonDialog1.FileName Open outfn For Output As #1 Print #1, txtData.Text Close #1 'txtData.SaveFile outfn lblStatus.Caption = "输出完成,空闲" errhandler: Exit Sub End Sub Private Sub Form_Load() lblStatus.Caption = "空闲" End Sub Private Sub Form_Unload(Cancel As Integer) '关闭端口 If MSComm.PortOpen = True Then MSComm.InBufferCount = 0 '清空缓冲区 MSComm.PortOpen = False End If End Sub Private Sub MSComm_OnComm() Dim T1, T2 As Long Select Case MSComm.CommEvent Case comEvReceive '收到Rthreshold个字节产生的接收事件 MSComm.RThreshold = 0 '关闭OnComm事件接收 lblStatus.Caption = "接收" av = MSComm.Input '读取一个接收字节 dataframe(1) = av(0) '转换为字节 If dataframe(1) = &HA Then '接收到T1 Do DoEvents Loop Until MSComm.InBufferCount >= 2 '循环等待接收缓冲区>=2个字节 av = MSComm.Input dataframe(2) = av(0) av = MSComm.Input dataframe(3) = av(0) '接收T1 T1 = dataframe(2) + CLng(dataframe(3)) * 256 '计算T1 End If Do DoEvents Loop Until MSComm.InBufferCount >= 1 '循环等待接收缓冲区>=1个字节 av = MSComm.Input '读取一个接收字节 dataframe(4) = av(0) '转换为字节 '接收到T2 If dataframe(4) = &HA0 Then 'MSComm.RThreshold = 0 '关闭OnComm事件接收 '循环等待接收缓冲区>=2个字节 Do DoEvents Loop Until MSComm.InBufferCount >= 2 av = MSComm.Input dataframe(5) = av(0) av = MSComm.Input dataframe(6) = av(0) '接收T2 T2 = dataframe(5) + CLng(dataframe(6)) * 256 '计算T2 '显示T1 T2 enter txtData.Text = txtData.Text + CStr(T1) + " " + CStr(T2) + Chr(&HD) + Chr(&HA) datacount = datacount + 1 '数据组数+1 End If MSComm.RThreshold = 1 '打开OnComm事件接收 Case Else End Select End Sub
以上。
吹空调的老狼