You are on page 1of 3

第27卷 第4期 计 算 机 工 程 2001年4月

Vol.27 4 Computer Engineering April 2001

开发研究与设计技术 文章编号 1000 3428(2001)04 0180 02 文献标识码 A 中图分类号 TP311.52

微机串行通信协议研究
李卫忠 雷英杰
(空军工程大学导弹学院计算机工程系 三原713800)
摘 要 在分析 VB串行通信控件MSComm属性的基础上 提出了针对 MSComm设计串行通信协议的一些原则和技巧 给出了编程代码
关键词 VB 串行通信 通信协议

Study on Protocol of Personal Computer's Serial Communication


LI Weizhong LEI Yingjie
(Department of Computer, Missile Institute, Air Force Engineering University,Sanyuan 713800)
Abstract This Paper analyzes the properties of MSComm control of VB, and gives out some principles and skills to design serial
communication protocol with MSComm control, related codes are also given.
Ke words VB Serial communication Communication protocol

MSComm是 VB带有的专门管理串行通信的控件 该 控 2 通信协议设计


件通过串行端口传输和接收数据 为应用程序提供串行通信 我们设计的协议包括3层 物理层 数据包装层 应 用
功能 探讨如何利用该控件 制作规范的协议 使得程序具 层 InputMode=1 发送接收选用字符方式
有较强的通用性 提高编程效率 2.1 物理层
1 MSComm 控件属性分析 该层主要负责合理设置控件属性 完成数据字符级的收
每个使用的 MSComm 控件对应一个串行端口 如果应 发功能 对发送 不采用中断方式 Sthreshold=0 程序中
用程序需要访问多个串行端口 必须使用多个 MSComm 控 根据处理需要 数据准备好时 启动output属性发送 接 收
件 可以在 Windows"控制面板 "中改变端口地址和中断地 采 用 中 断 方 式 Rthreshold=1 每 次 接 收 一 个 字 符 产 生
址 Windows最多可支持16个串口 可根据需要 扩充微机 OnComm 事件 将数据从通信缓冲区取出 放到自己定义
的串口 市场上有很多品牌的多用户卡 能完成此项功能 的 字 符 队 列 里 例 如 设 计 一 个 Form 窗 体 添 上 几 个
MSComm 控件有很多重要的属性 首先必须熟悉以下 MSComm控件 将下面的代码加入到程序中 一些全局变
几个属性 量在模式文件里定义 NmaxCommPort为控件数目 每 个
属性 描述 控件对应一个端口 InString为用户自定义接收缓冲区 用
CommPort 设置并返回通信端口号 来暂存从通信缓冲区取得的字符 Ncount为缓冲区 InString
Settings 以字符串的形式设置并返回波特率
中字符个数 MSCommOk为端口状态 对于存在的端口
奇偶校验 数据位 停止位
PortOpen 设置并返回通信端口的状态
打开状态为 True 才能进行接收和发送
Public nCount(NmaxCommPort) As Long
也可以打开和关闭端口
Private Sub Form_Load()
Input 从接收缓冲区返回和删除字符
Dim i As Integer
Output 向传输缓冲区写一个字符串
For i =0 to NmaxCommPort
InputMode 0 以文本形式取回数据 1
Comm(i).Settings="9600,n,8,1"
以二进制形式取回数据
Comm(i).InputMode=0 '字符方式
Rthreshold 当接收字符后 若 Rthreshold 属性设置为 0
Comm(i). Rthreshold =1 '打开 Receive 事件陷阱
缺省值 则不产生 OnComm事件
Comm(i). Sthreshold =0 '关闭 Send 事件陷阱
Rthreshold为 1 接收缓冲区收到每一个字符
Next I
都会使 MSComm控件产生 OnComm 事件
Call MSCommOpen
Sthreshold 属性为 0 缺省值 数据传输事件不会产生
End Sub
OnComm 事件 若设置Sthreshold 属性为 1
Sub MScommOpen()
当传输缓冲区完全空时 MSComm 控件产生
On Error GoTo ErrHandler
OnComm 事件
Dim i As Integer
MSComm 控件提供下列两种处理通信的方式 (1)中 断
For i = 0 To NmaxCommPort - 1
方式 是处理串行端口交互作用的一种非常有效的方法 可 MSCommOk(i) = True
以利用 MSComm 控件的 OnComm 事件捕获并处理这些通
信事件 (2)查询方式 在程序的每个关键功能之后 可 以 作者简介 李卫忠(1968 ) 男 讲师 硕士 主研方向为计算
通过检查 CommEvent 属性的值来查询事件和错误 机应用 雷英杰 教授 博导
收稿日期 2000-08-30
180
nCount(i) = 0 Case comFrame 'Framing Error
Comm(i).PortOpen = True Case comOverrun 'Data Lost
Next i Case comRxOver 'Receive buffer overflow
Dim Nok As Integer Case comRxParity 'Parity Error
Nok = 0 Case comTxFull 'Transmit buffer full
For i = 0 To NmaxCommPort - 1 End Select
If (MSCommOk(i) = True) Then Nok = Nok + 1 End Sub
Next i
Private Sub Form_QueryUnload(Cancel As Integer, Unload
If (Nok = 0) Then
Mode As Integer)
Dim Msg As String 'Declare variable
Cancel = 1
Dim Style As String 'Declare variable
End Sub
Dim Title As String 'Declare variable
Private Sub Form_Unload(Cancel As Integer)
Msg = Chr$(13) + Space$(5)
Call MScommClose
Msg = Msg + "串行端口正在被使用 ! " + Space$(8) + Chr$
End Sub
(13) + Chr$(13)
Msg = Msg + Space$(5) + "请关闭有关程序 " + Chr$ ( 2.2 数据包装层
13) 该层主要对数据进行包装发送 接收时去掉包装 选用
Style = vbOKOnly + vbCritical ' Define buttons 字符方式进行通信 主要是为了在字符中插入某些控制字
MsgBox Msg, Style, 'Display message
符 用以识别数据是否组装好 对所有要发送的数据组装成
End
End If
可见的ASCII码字符串 数据组装好后 在字符串后加上不
Exit Sub 可见控制字符 Chr(13) 然后启动数据发送 接收时 根据
ErrHandler: 是否收到控制字符 Chr(13) 来判断是否收到完整信息包
MSCommOk(i) = False 将以下程序作为一个模式文件加入到项目中 这层协议提供
Resume Next
的软件接口为 发送调用过程 MSCommSend() 接收调用
End Sub
Sub MScommClose()
函 数 GetMsgfromCom() 如果数据组装好 函数返回
Dim i As Integer True 将以下程序保存在一模式文件里
On Error Resume Next Option Explicit
' Close MSComms Public Const NmaxCommPort = 16 '通信控件数目
For i = 0 To NmaxCommPort - 1 Public MSCommOk(NmaxCommPort) As Boolean
Comm(i).PortOpen = False ' 通信控件状态
Next i Public InString(NmaxCommPort) As String
End Sub ' 每个控件一个接收缓冲区
Sub comReceive(Index As Integer) Public nCount(NmaxCommPort) As Long
Dim RS$ '缓冲区中字符计数
If (Comm(Index).InBufferCount <= 0) Then Exit Sub Public Function GetMsgfromCom(PortNum As Integer,
Comm(Index).InputLen = 0 MsgStr As String) As Boolean
'Default, Retrieve all available data Dim i As Integer
RS$ = Comm(Index).Input 'Read data
For i = 0 To NmaxCommPort - 1
InString(Index) = InString(Index) + RS$
nCom = (nCom + 1) Mod NmaxCommPort
End Sub
If MSCommOk(nCom) And InString(nCom) <> "" Then
'事件发生 从通信缓冲区取出放到 InString 中
Exit For
Private Sub Comm_OnComm(Index As Integer)
Next i
Select Case Comm(Index).CommEvent
If (i = NmaxCommPort) Then
Case comEvReceive ' Received RThreshold # of chars.
GetMsgfromCom = False '无信息
Call comReceive(Index)
Case comEvCD 'Change in the CD line Exit Function
Case comEvCTS ' Change in the CTS line End If
Case comEvDSR ' Change in the DSR line i = InStr(InString(nCom), Chr$(13))
Case comEvRing 'Change in the Ring Indicator If (i = 0) Then
Case comEvSend 'There are SThreshold number of GetMsgfromCom = False '无信息
' characters in the transmit buffer. If (Len(InString(nCom)) > 600) Then InString(nCom) =
Case comEvEOF ' An EOF charater was found in Right$(InString(nCom), 600)
Case comBreak 'A Break was received Exit Function
Case comCDTO 'CD (RLSD) Timeout End If (下转第 187页 )
Case comCTSTO 'CTS Timeout
Case comDSRTO 'DSR Timeou.

181
5 结论 时 不同的单词对该概念的细化程度是不同的 也就是说它
概念频率统计方法保留了统计方法速度快 效率高的特 们在表达该概念的强度上是分层次的 在以后的概念频率统
点 同时又改进了词频统计方法缺乏语义分析的缺点 该方 计中应该考虑这种现象
法通过运用知识库进行一定程度的语义分析 以概念为单位 参考文献
1 Michael H,Hasan R.Cohesion in English. Longman Group
处理文本 提高了提取主题的质量
Ltd.,1976
我们的方法还有以下几方面需要改进 2 Miller G A,Beckwith R,Fellbaum R,et al.Five Papers on WordNet.
概念联系的多样性 词汇之间具有的概念关系是多样 GSLReport 43,Cognitive Science Laboratory,Princeton University,
的 有些概念之间会互相增强 有些概念之间却会彼此消 1993
减 并且概念互相增强的途径也是多种多样的 本文目前仅 3 Stairmand, Mark A.A Computational Analysis of Lexical
Cohesion with Applications in Information Retrieval [Ph.D.
考虑了由重复性内聚关系引起的概念增强的现象 其余几种 Thesis].Center for Computational Linguistics,UMIST,Manchester,
概念关系还有待研究 1996
概念频率统计的精确性 当一组单词表达同一概念

(上接第 181页 ) Dim s1 As String


PortNum = nCom s1 = Format$(Msg1.Tr1, "00000.000") + Format$(Msg1.
If(i>1)Then '取信息串 ,但不包含回车字符 Chr$(13) Tr2, "00000.000")
MsgStr = Left$(InString(nCom), i - 1) s1 = s1 + Format$(Msg1.Sd1, "00000") + Format$(Msg1.
Else Sd2, "00000")
MsgStr = "" Call MSCommSend(port, s1)
End If End Sub
If (Len(InString(nCom)) > i) Then Function GetMsg(port As Integer, Msg1 As MyMsg)
InString(nCom) = Right$(InString(nCom), Len(InString ( Dim s1 As String
nCom)) - i) If (GetMsgfromCom(port, s1) = False Or Len(s1) < 28) Then
Else Get_keys = False
InString(nCom) = "" Exit Function
End If End If
GetMsgfromCom = True Msg1.Tr1 = Mid$(s1, 1, 9)
End Function Msg1.Tr2 = Mid$(s1, 10, 9)
Public Sub MSCommSend(Port As Integer, SndStr As String) Msg1.Sd1 = Mid$(s1, 19, 5)
SndStr= SndStr + Chr$(13) Msg1.Sd2 = Mid$(s1, 24, 5)
If (MSCommOk(Port) = True) Then End Function
Sio.Comm(Port).output = SndStr 对于每种通信格式 数据长度必须严格定义 否则数据
End If
将混乱 实际应用中对各串口可有不同的应用层协议 即便
End Sub
是同一端口 数据通信格式也可能会有变化 不同数据格式
以上两层协议具有通用性 不同应用程序只需将窗体文
件和模式文件加入到自己项目中即可 可定义不同的长度 接收数据时根据不同长度来分别进行数
2.3 应用层 据组装
该层协议主要负责将用户信息按一定格式组装成可见的 3 结论
ASCII 码 字 符 串 然 后 调 用 数 据 包 装 层 提 供 的 接 口 程 序 我们采用上述协议 已经在防空C3I 防空武器训练模
MSCommSend()发送数据 接收时 先调用数据包装层提供 拟器 磷肥工业控制系统等诸多领域成功地实现了微机间和
的接口程序 GetMsgfromCom() 数据到齐后 按照组装顺序 微机与单片机之间的串行通信 在这些应用中 前 2层 协 议
进行拆解 该层具体协议 需要根据通信内容和软件需求来 完全相同 只要简单地根据需要修改应用层 就能大大提高
定义 下面以实际应用中一例来介绍这层协议如何具体制
开发效率

Public Type MyMsg '自定义数据结构
参考文献
Tr1 As Single 1 谭 灏,鄂卓茂 .Visual Basic MSComm控件下的微机串行通信 .计
Tr2 As Single 算机工程 1999,25(7):98
Sd1 As Integer 2 王文峰 .利用 VB的 Binary方式开发通用串行通信软件 .计算机应
Sd2 As Integer 用 ,1999(12)
End Type 3 Sile B.Visual Basic 6开发使用手册 .北京 机械工业出版社 ,1999
Sub SendMsg(port As Integer, Msg1 As MyMsg)

187

You might also like