上位机可方便地实现与单片机之间进行信息传递交互,能够更加容易对机械手臂进行控制,实现操作可视化,更加直观,保存重要数据等功能。我们利用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控件,并在窗体装入时进行初始化
vb软件开发Private Sub Form_Load()
MSComm1.CommPort = 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
MSComm1.CommPort = 1
ElseIf Combo1.Text = "COM2" Then
MSComm1.CommPort = 2
ElseIf Combo1.Text = "COM3" Then
MSComm1.CommPort = 3
Else
MSComm1.CommPort = 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 MSComm1.CommEvent
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 ‘整个成四位数显示到文本框中
三:这样上位机的基本部分完成,下面编制二级窗体,来进行永久保存数据,即将程序运行过程中处于内存中的数据保存到硬盘中的指定路径,以便下次再运行时调用,否则当程序关闭后内存释放,再打开上位机处于最初状态,仍然需要输入相应数据。
向项目中添加窗体,首先绘制界面,文本框与控件组形式存在。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论