VB编写上位机(MSComm控件)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
上位机可方便地实现与单片机之间进行信息传递交互,能够更加容易对机械手臂进行控制,实现操作可视化,更加直观,保存重要数据等功能。
我们利用Visual Basic 6.0(以下简称VB)来编制上位机,VB是一种功能强大、简单易学的程序设计语言。
它不但保留了原先Basic语言的全部功能,而且还增加了面向对象程序设计功能。
它不仅可以方便快捷地编制适用于数据处理、多媒体等方面的程序,而且利用ActiveX控件MSComm还能十分方便地开发出使用计算机串口的计算机通信程序。
本实验涉及控制六路舵机,所以需要编制上位机实现一次向下位机传输含有六个数据的数组,同时接受来自下位机的数组,并显示。
整个过程可分为如下几个过程:
一:VB是面向对象的语言,首先需要绘制程序界面
该上位机大致分为左边的功能部分与右边的可视化调节部分。
功能部分有端口选择,用以选择合适的端口进行串口通信,波特率选择,打开与关闭端口,动作设置等。
为了便于布局,应用frame控件建立区域,再将控件拖到frame区域中,对于功能相同的控件来说,建立控件组的方式会使编程避免重复繁琐,例如HScrollbar控件,先向frame区域内拖入一个HScrollbar控件,再复制,粘贴到frame 区域内部,则提示是否建立控件组,点击确定即可。
这样便为后续编程带来很大的方便。
调节部分运用Hscrollbar控件来粗略调节度数,设定按钮与文本框配合来精确调节输出度数。
用右列文本框实时读取舵机当前角度。
用optionbutton控件来选择hscrollbar的步进精度,这里分为0.1度与1度两个不同的选项。
由于一组optionbutton中在程序运行中只能有一个处于选中状态,根据本程序要求,每一横列的两个optionbutton为一组,这样就需要frame控件,在同一个frame区域
里的optionbutton默认为一组。
这样就可以如上图所示的状态显示,否则真能选中其中的一个。
端口与波特率的选择应用combobox控件。
指示灯部分则用picturebox控件添加两个图片,分别为红灯与黑灯,用以显示端口的开关状态。
每个MSComm控件对应于一个串行端口。
使用多个串行口时,要使用多个MSComm控件。
MSComm控件的主要属性及说明如下。
“工程”——“部件”,选中Microsoft Comm control 6.0,“确定”,完成MSComm 控件的添加。
二:在完成了界面的绘制后,就需要对部分的控件的初始属性进行设置。
并输入
有两种处理通信的方式:
(1)事件驱动。
利用OnComm事件捕获并处理通信事件,所有的通信事件和通信错误列表都包含在控件的CommEvent属性中。
(2)查询方式。
在程序关键功能之后,通过检查CommEvent的值来查询事件和错误。
添加MScomm控件,并在窗体装入时进行初始化
Private Sub Form_Load()
mPort = 1 ’端口选择1
MSComm1.Settings = "9600,N,8,1’定义数据传输协议,与下位机要保持一致。
波特率9600,无奇偶验证,8个数据位,一个停止位。
MSComm1.InputMode = 1'数据传输为二进制方式
MSComm1.InBufferCount = 0 '清空接受缓冲区
MSComm1.RThreshold = 1 '产生MSComm事件
If MSComm1.PortOpen = False Then
MSComm1.PortOpen =True '打开串口
End If
End Sub
为随时判断端口是否开启,并用黑红等来显示当前状态,运用timer控件,将interval设置为100,双击控件并输入如下代码。
则程序每隔100ms执行一次下面的程序。
Private Sub Timer2_Timer()
If MSComm1.PortOpen = ture Then
Picture1.Visible = True
Picture2.Visible = False’对应红灯图片显示,黑灯图片不显示。
Else
Picture2.Visible = True
Picture1.Visible = False’对应黑灯图片显示,红灯图片不显示。
End If
End Sub
运用combobox控件来选择端口,波特率等MSComm的setting值,双击控件后输入如下代码
Private Sub Combo1_Click()
If Combo1.Text = "COM1" Then
mPort = 1
ElseIf Combo1.Text = "COM2" Then
mPort = 2
ElseIf Combo1.Text = "COM3" Then
mPort = 3
Else
mPort = 4
End If
End Sub
则选择端口部分完成。
波特率部分同理。
本项目向单片机传输的为六个1000~5000之间的整数,所以要将HScroll的min 值设为1000,max值设为5000。
1000~5000与角度0~180度之间相对应,即运用一次函数形式将HScroll.value值转变为度数赋给对应HScrollbar下方的文本框。
Private Sub HScroll1_Change()
Text1.Text = Format(HScroll1.Value * 0.045 - 45, "0.0")
End Sub
同时如果在文本框中输入0~180之间的度数,点击“设定”按钮,需要将其度数对应的数值赋给HScroll.value,这样度数与Hscrollbar进度条之间便一一对应了。
Private Sub Command3_Click()
If Text1.Text = "" Then
MsgBox "未输入数值", 5, "警告" ‘出现警告的提示框,提示”未输入数值”。
ElseIf Text1.Text < 0 Or Text1.Text > 180 Then
MsgBox "0-180为有效数值", 5, "警告" ’出现警告的提示框,提示"0-180为有效数值"
Else
HScroll1.Value = Format((Text1.Text + 45) * 200 / 9, 0) ’仅保留个位数。
End If
End Sub
由于PC与单片机之间的数据传输要以字节型数据传输,而字节数据的范围为0~256,所以本项目中将每个整数分成两个部分,千位与百位为一个数,个位与十位为一个数,即要想传送3456,则分别传送34与56两个数据,然后由下位机还原回3456。
这样可以建立一个包含12个数据的字节型数组用以传输数据。
先用包含6个数据的字符型数组储存6个四位数,再用Mid()函数来提取前两位与后两位然后将数据赋给包含12个数据字符型数组储存12个两位数,最后将此数组转换字符型数组。
具体过程如下
建立输出函数
Sub mytest()
Dim senddata(0 To 5) As String
Dim rr(1 To 12) As String
Dim yy(1 To 12) As Byte
Dim i As Integer
Dim j As Integer
Dim k As Integer
For k = 0 To 5
senddata(k) = HScroll1(k).Value
Next k
For i = 1 To 6
rr(2 * i - 1) = Mid(senddata(i - 1), 1, 2)
rr(2 * i) = Mid(senddata(i - 1), 3, 2)
Next i
For j = 1 To 12
yy(j) = rr(j)
Next j
MSComm1.Output = yy
End Sub
设定HScroll1为一个控件数组,在其中运用call,则HScroll每改变一下位置,就会执行上述函数来向下位机发送数据,这就保证了上位机的实时性。
由于上位机还需要发传感器等数据,为了便于下位机区分,先发送一个与下位机约定好的命令字节,如“A”发送后延时一段时间,以便让下位机准备接受此类数据。
call 以上函数,完成发送数据。
以下为完整代码:
Private Sub HScroll1_Change(Index As Integer)
MSComm1.Output = "A"
Delay (500) ‘延时500ms
Call mytest
End Sub
其中delay为延时函数,添加模块后在其中定义:
Public Declare Function timeGetTime Lib "winmm.dll" () As Long
Public Sub Delay(ByVal num As Integer)
Dim t As Long
t = timeGetTime
Do Until timeGetTime - t >= num
DoEvents
Loop
End Sub
接收数据部分未发送数据的逆过程,运用oncomm事件来触发接收。
由于下位机会发来不同长度的信息,为了使上位机判断是哪一种数据,同样可以使用上面例
子中的方式,先发一个命令字节、延时、接受。
这里我们用另一种方法,在数据前加一个开始字符,与数据一同发过来,上位机根据首字符而相应的选择数据的处理方式,当然事先要与下位机约定好。
双击MScomm控件,输入代码。
Private Sub MSComm1_OnComm()
Dim aa(1 To 6) As String
Dim bb(100) As Byte
Dim Buffer As Variant
Dim i As Integer
Dim j As Integer
Select Case mEvent
Case 2
Timer1.Enabled = True 定时器打开
MSComm1.InputLen = 0 一次性全部读入
MSComm1.RThreshold = 0 禁止生成事件
Buffer = MSComm1.Input
For i = LBound(Buffer) To UBound(Buffer)
bb(i) = Buffer(i)
Next i
If bb(0) = 65 Then
For j = 1 To 6
aa(j) = bb(2 * j - 1) * 100 + bb(2 * j - 0)
Text7(6 - j).Text = aa(j)
Next j
ElseIf bb(0) = 66 Then
bb(0) = 66
For j = 1 To 6
aa(j) = bb(2 * j - 1) * 100 + bb(2 * j - 0)
Text7(6 - j).Text = aa(j)
Text9.Text = bb(2)
Next j
ElseIf bb(0) = 67 Then
Text9.Text = bb(2)
End If
End Select
End Sub ‘整个成四位数显示到文本框中
三:这样上位机的基本部分完成,下面编制二级窗体,来进行永久保存数据,即将程序运行过程中处于内存中的数据保存到硬盘中的指定路径,以便下次再运行时调用,否则当程序关闭后内存释放,再打开上位机处于最初状态,仍然需要输入相应数据。
向项目中添加窗体,首先绘制界面,文本框与控件组形式存在。
点击主界面上的“动作一”按钮进入二级窗口,代码如下:
Private Sub Command11_Click()
Form2.Show
End Sub
这里输入六组数据,每组为舵机的转动终点角度,这样机械手臂按顺序执行下去,生成一连串的动作。
“永久保存”可在制定路径上生成txt文件用以保存已经调试好的数据,在下次用的时候可点击“载入数据”来调入上次保存的数据,点击发送可将这组数据全部发送给单片机。
保存数据程序:
Private Sub Command3_Click()
Dim i As Integer
Open "C:\Users\test\Desktop\2.txt" For Output As #2‘保存在桌面上,文件名为2.txt
For i = 0 To 35
Print #2, Text1(i).Text
Next i
Close #2
End Sub
载入数据程序
Private Sub Command4_Click()
Dim j As Integer
Dim i As Integer
Open "C:\Users\test\Desktop\2.txt" For Input As #2
Do While Not EOF(2)
For j = 0 To 35
Line Input #2, outputdatas(j)
Next j
Loop
For i = 0 To 35
Form3.Text1(i).Text = outputdatas(i)
Next i
Close #2
End Sub
其中outputdatas为全局变量,字符型数组。
定义时用如下方法,在工程中“添加模块”,并在模块中输入Public outputdatas(0 To 35) As String即可完成定义,这样此数据不会在程序执行过程中释放地址,并应用于全局。
点击“发送”按钮,将数据outputdatas按步骤二中发送的方式首先转换数据类型,然后送入output即可完成发送这35个数据的发送。
四:调试。
在编制过程中难免会有些疏漏和一些没有考虑的情况,而且根据项目中硬件软件的具体情况也要对上位机进行一些调整,是整个系统达到最佳状态。