摘 要:介绍了用Visual Basic语言的MSCOMM串行通信控件实现计算机与多单片机通信编程的一个详细的实例,提出一种实现多机通信的新思路,该方法易于编程,较为实用。
关键词: Visual Basic;单片机;多点通信;程序
目前,随着单片机及微机技术的不断发展,单片机组网技术越来越成熟,集散测控系统应用越来越广泛。它既利用了单片机性价比高和面向控制等优点,又结合PC机具有丰富的软硬件资源,特别是非常友好的人机界面等特点。在这种系统中,单片机主要进行实时数据采集及预处理,然后通过串行口将数据传送给PC机,PC机对这些数据进一步处理。
在Windows环境下实现串行通信一般有4种方法:底层汇编操作;用某些高级语言(如C、PASCAL)提供的库函数;用Windows提供的API函数;用串行通信控件MSCOMM;这几种方法有各自的优缺点,使用局限性也各不相同。有些通信方法可直接对串行口地址位操作,在此方式中,可传送一帧11位的信息:1位起始位,8位数据位,1位可作“地址帧”和“数据帧”的标志位和1位停止位。这可很方便实现多机通信(单片机通信方式2、3),但其复杂化和专业化程度高。串行通信控件MSCOMM只能送一帧10位的信息,取8位数据位,1位起始位,1位停止位,则不利于多机通信,但它可在现在应用非常广泛的可视化程序设计语言Visual Basic中引用,简明易用。下面我们来探索一种用VB语言实现PC机与多台单片机通信的方法,这种方法已成功应用于多点温湿度监测系统中,取得了良好的效果。
1 程序整体设计考虑
VB作为面向对象的可视化程序设计语言,以其高效、简单易学及功能强大的特点越来越为广大程序设计人员及用户所青睐。在串行通信方面,VB提供了一个标准的十位通信控件MSCOMM(电话盒)。我们应用的单片机大多8位为一个字节(如11000100),这就是说我们不能在MSCOMM数据帧中设置奇偶校验位或“地址帧”和“数据帧”的标志位。这样MSCOMM控件能方便实现单机通信,但不利于多机通信。由于在一般的集散测控系统中,上位PC机与下位机之间相互传送的数据一般不多。所以我们可将上位PC机发送给下位机的数据和下位机发送给上位机的数据设定在不重叠的区域内,使下位机能区分地址(命令)和数据,则可实现多机通信。在我们开发的监测系统中,下位机传送给上位PC机的数据全为BCD码(0-9),上位PC机传送给下位机的数据大于0F0H(十六进制),这样互不干扰。下面以我们开发的实例来介绍这种方法。
2 上位机VB程序设计方法
在通信协议中,每台下位单片机都规定了明确的地址码(通过拨码开关设定或编程时固定)。PC机发送出一个数据(地址或命令)给下位机后等待下位机的反应。下位机接收到地址或命令后,比较确认,作出反应。以下是已在监测系统中用到的一个完整的通信程序,下位机只设两台,注意将PC机程序与单片机程序结合起来分析。
Dim res(10,2) As Integer //定义一些全局变量
Dim wen(2) As Single
Dim jy(2) As Single
Dim dz(2) As Single
Dim n As Single
Dim m As Single
Private Sub Form_Load() //变量及串口初始化
m = -1
wen(0)=0
wen(1)=0
MSComm1.CommPort=1 //设置串口1
MSComm1. Settings="9600,n,8,1" //波特率:9600,不作同位检查,8位数据位,1位停止位
MSComm1.PortOpen = True //打开串口1
End Sub

Private Sub Timer1_Timer() //定时器定时激活通信程序
100
If m > 1 Then m = -1
MSComm1.InputLen = 0 //读取接收缓冲区所有字符
m = m + 1
MSComm1.Output = Chr(128- m) //发送地址码,注意它大于9(下位机数目不很多的情况下),与数据码区分,下位机有相应的处理程序
For i = 1 To 7
MSComm1.InputLen = 1 //一次接收一个字节
n = 0
Do
Dummy= DoEvents()
n = n + 1
If n > 500 Then GoTo 100;n循环值要取大一点
Loop Until (MSComm1.InBufferCount > 0) //接收数据触发事件
res(i, m) = Asc(MSComm1.Input) //接收数据在res( )数组中
Next i
dz(m) = res(1, m) & res(2, m) //单片机发送回来的检验地址
wen(m) = res(3, m) & res(4, m) & res(5, m) //下位单片机8位A/D转换器采集到的空气温度值
jy(m) = res(6, m) & res(7, m) //和校验码
wen(m) = wen(m) / 8.3 //数据处理
If dz(m) <> 47 - m Then GoTo 100 //地址是否正确
If jy(m) <> res(3, m) + res(4, m) + res(5, m) Then GoTo 100 //和校验
Text1.Text = wen(0) //显示0点温
Text2.Text = wen(1) //显示1点温度
End Sub