找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9041|回复: 1
上一主题 下一主题
收起左侧

VB.NET上位机开发

[复制链接]
跳转到指定楼层
楼主
ID:37685 发表于 2014-10-21 01:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  说明:本文在编辑的时候,是直接从事先写好的Word文档中复制过来的,图片都没有粘贴过来,完整资料请上百度下载。上百度搜索“VB.NET上位机快速开发教程”即可,格式为PDF,上面有湖北文理学院的图标。在编写此日志的时候,该文档正在百度文库和新浪爱问共享资料审核中,如无法搜到本文档,请稍等片刻或者与本人联系,我将通过邮箱发送。源码下载地址在本文末尾可以看到!
一、准备工作
一台装有VS2010的计算机,用于测试的虚拟串口软件。同时你必须具有VB基础知识,这个VB上位机开发是入门级的,仅将VB.NET通信基础方法稍作介绍。
二、串口通信常识
在串口通信中,通过编写单片机程序知道,我们应对如下参数进行设置:波特率、数据位和停止位、奇偶校验位。如果自己编写上位机的时候,我们考虑的不能仅仅是这些了,下面介绍上位机开发过程中需要特别注意的知识点。
MSComm控件提供了两种处理通信的方式:一种为事件驱动方式,该方式相当于一般程序设计中的中断方式。当串口发生事件或错误时,MSComm控件会产生OnComm事件,用户程序可以捕获该事件进行相应处理。
常用属性和方法     
利用MSComm控件实现计算机通信的关键是理解并正确设置MSComm控件众多属性和方法。以下是MSComm控件的常用属性和方法:     
  ●Commport设置或返回串口号。其值从COM1到COM16。     
  ●Settings以字符串的形式设置或返回串口通信参数。     
  ●Portopen设置或返回串口状态。     
  ●InputMode设置或返回接收数据的类型。有文本和二进制两种类型。     
  ●Inputlen设置或返回一次从接收缓冲区中读取字节数。     
  ●InBufferSize设置或返回接收缓冲区的大小,缺省值为1024字节。     
  ●InBufferCount设置或返回接收缓冲区中等待计算机接收的字符数。
Input:从接收缓冲区中读取数据并清空该缓冲区,该属性设计时无效,运行时只读。
OutBufferSize设置或返回发送缓冲区的大小,缺省值为512字节。     
  ●OutBufferCount设置或返回发送缓冲区中等待计算机发送的字符数。     
  ●Output向发送缓冲区发送数据,该属性设计时无效,运行时只读。     
  ●Rthreshold该属性为一阀值。当接收缓冲区中字符数达到该值时,MSComm控件设置Commevent属性为ComEvReceive,并产生OnComm事件。用户可在OnComm事件处理程序中进行相应处理。若Rthreshold属性设置为0,则不产生OnComm事件。例如用户希望接收缓冲区中达到一个字符就接收一个字符,可将Rthreshold设置为1。这样接收缓冲区中接收到一个字符,就产生一次OnComm事件。     
  ●Sthreshold该属性亦为一阀值。当发送缓冲区中字符数小于该值时,MSComm控件设置Commevent属性为ComEvSend,并产生OnComm事件。若Sthreshold属性设置为0,则不产生OnComm事件。要特别注意的是仅当发送缓冲区中字符数小于该值的瞬间才产生OnComm事件,其后就不再产生OnComm事件。例如Sthreshold设置为3,仅当发送缓冲区中字符数从3降为2时,MSComm控件设置Commevent属性为ComEvSend,同时产生OnComm事件,如发送缓冲区中字符始终为2,则不会再产生OnComm事件。这就避免了发送缓冲区中数据未发送完就反复发生OnComm事件。     
  ●CommEvent这是一个非常重要的属性。该属性设计时无效,运行时只读。一旦串口发生通信事件或产生错误,依据产生的事件和错误,MSComm控件为CommEvent属性赋不同的代码,同时产生OnComm事件。用户程序就可在OnComm事件处理程序中针对不同的代码,进行相应的处理。
三、开发步骤(仅供参考)
1.     运行VS2010,新建一个Visual Basic的Windows窗体应用程序项目。将窗体的StartPosition属性改为CenterScreen,运行程序时,窗体在屏幕中央显示。


  
2.     由于默认情况下,通信所需的“Microsoft Communications Control,version 6.0”组件不在工具箱里面,所以我们需要手动添加。单击左侧的工具箱,并在控件栏单击鼠标右键,在弹出的菜单中选中“选择项”,在弹出的对话框中单击“COM组件”并选中“MicrosoftCommunications Control,version 6.0”,单击确定即可完成添加。此时移动鼠标到窗体上时,鼠标箭头就会变成电话的形状,在窗体任意位置单击放置该控件。

3.     单击工具箱,在窗体上添加5个Label,并在属性里将Text属性依次改为:串口号、波特率、校验、数据位、停止位。再向窗体上添加5个ComboBox,从上到下依次排列。
4.     向窗体添加一个OvalShape和一个Button。将OvalShape的size属性改为“24,24”,FillStyle改为Solid。
5.     向窗体添加一个CheckBox、一个按钮Button和一个TextBox,将CheckBox的Text属性改为“十六进制发送”将这个按钮的text属性改为“发送”。
6.     向窗体添加一个Label和一个TextBox。更改Label的Text属性为“接收区”。
7.     向窗体添加一个CheckBox,将其Text属性改为“十六进制显示”

下面将要对部分控件进行设置,这样可以减少代码的长度
四、源代码
Public Class Form1
    Dim cpSetting As String
    Dim com_last_num As Integer = 0   '定义一个全局变量,作用为记录上一个串口号
    Sub GetSerialPortNames() '搜索计算机中所有可用串口函数
        On Error GoTo eRRHND '错误处理
        '搜索计算机中可用串口
        For Each sp As String In My.Computer.Ports.SerialPortNames
            ComboBox1.Items.Add(sp)
        Next
        ComboBox1.Sorted = True
        ComboBox1.SelectedIndex = 0 '选择搜索到的第一个串口名称
        Exit Sub
eRRHND:  '表示未搜到串口
        MsgBox("Oh, NO!")
    End Sub
    '检测串口是否可用函数
    Private Function Test_COM(ByVal com_num As Integer) As Boolean
        If com_num <> com_last_num Or Button1.Text = "打开端口" Then '如果选择的端口跟上次一样就不检测了
            On Error GoTo Comm_Error
            AxMSComm1.CommPort = com_num '将新串口号赋给ComPort
            AxMSComm1.PortOpen = True '打开串口
            AxMSComm1.PortOpen = False '关闭串口
            Test_COM = True            '串口可用则返回
            Exit Function
Comm_Error:  '根据错误号作出相应处理
            If Err.Number = 8002 Then
                MsgBox("串口错误,请重新选择串口", vbOKOnly, "错误提示!")
            ElseIf Err.Number = 8005 Then
                MsgBox("串口已打开!")
            Else
                MsgBox("其它错误")
            End If
            Test_COM = False         '如果出错,则返回0
            Exit Function
            Resume Next
        End If
    End Function
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        '载入窗体初始化
        GetSerialPortNames() '将搜到的串口在下拉菜单中显示出来
        AxMSComm1.InBufferSize = 1024 '接收缓冲区大小,此项无法在串口打开时进行设置
        AxMSComm1.OutBufferSize = 1024 '发送缓冲区大小
        ComboBox2.Text = "9600"
        ComboBox3.Text = "无校验"
        ComboBox4.Text = "8"
        ComboBox5.Text = "1"
        ChangePortProperty()
        '设置接收数据的格式为二进制
        AxMSComm1.InputMode = MSCommLib.InputModeConstants.comInputModeBinary
        AxMSComm1.InputLen = 0 '设置从缓冲区读取全部数据
        AxMSComm1.RThreshold = 1 '设置接收串口OnCommon事件
        AxMSComm1.PortOpen = True '打开串口
        If AxMSComm1.PortOpen = True Then
            OvalShape1.FillColor = Color.Green 'OvalShape颜色设为绿色
            Button1.Text = "关闭端口" '按钮上的文字显示为关闭端口
        Else
            OvalShape1.FillColor = Color.Red 'OvalShape颜色设为红色
            Button1.Text = "打开端口" '按钮上的文字显示为打开端口
        End If
    End Sub
    '打开关闭串口代码
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim ptNum As Integer
        '通过串口名称获取串口号
        If Len(ComboBox1.SelectedItem) > 4 Then
            ptNum = Val(Microsoft.VisualBasic.Strings.Right(ComboBox1.Text, 2))
        Else
            ptNum = Val(Microsoft.VisualBasic.Strings.Right(ComboBox1.Text, 1))
        End If
        If AxMSComm1.PortOpen = False Then '如果串口是关闭的
            If Test_COM(ptNum) = True Then '如果选择的串口可用?
                '     ChangePortProperty()
                AxMSComm1.PortOpen = True '则打开该串口
                Button1.Text = "关闭端口" '按钮上的文字显示为关闭端口
                OvalShape1.FillColor = Color.Green 'OvalShape颜色设为绿色
            End If
        Else
            AxMSComm1.PortOpen = False '关闭该串口
            OvalShape1.FillColor = Color.Red 'OvalShape颜色设为红色
            Button1.Text = "打开端口" '按钮上的文字显示为打开端口
        End If
    End Sub
    '如下是访问网站的链接的代码,可以选择访问网站的浏览器,这里只使用默认的IE浏览器
    Private Sub LinkLabel1_LinkClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.LinkLabelLinkClickedEventArgs) Handles LinkLabel1.LinkClicked
        LinkLabel1.LinkVisited = True
        System.Diagnostics.Process.Start("www.baidu.com/p/huzhiqianglz")
    End Sub
    '处理发送数据的代码
    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim hexString() As Byte
        Dim source_Txt As String
        Dim i As Integer
        source_Txt = TextBox1.Text '将要发送的数据存放到变量source_Txt中
        If CheckBox1.CheckState = CheckState.Checked Then '如果十六进制发送复选框被勾上
            If Len(source_Txt) Mod 2 = 0 And Len(source_Txt) <> 0 Then '如果将要发送的数据长度不为或者能被2整除
                ReDim hexString(Len(source_Txt) / 2 - 1) '重新定义hexString数组
                For i = 0 To Len(source_Txt) - 1 Step 2
                    hexString(i / 2) = Val("&H" & Mid(source_Txt, i + 1, 2)) '将hexString转换成十六进制显示
                Next
                AxMSComm1.Output = hexString '将转换的数据发送到串口
            Else '否则提示格式不正确
                MsgBox("格式不正确!")
            End If
        Else '否则输出字符串
            AxMSComm1.Output = TextBox1.Text
        End If
    End Sub
    Sub ChangePortProperty()
        Dim comSetting As String
        Dim parity As String = ""
        '关闭端口
        If AxMSComm1.PortOpen = True Then
            AxMSComm1.PortOpen = False
        End If
        '获取串口号
        If Len(ComboBox1.SelectedItem) > 4 Then
            AxMSComm1.CommPort = Val(Microsoft.VisualBasic.Strings.Right(ComboBox1.Text, 2))
        Else
            AxMSComm1.CommPort = Val(Microsoft.VisualBasic.Strings.Right(ComboBox1.Text, 1))
        End If
        '设置校验方式
        If ComboBox3.Text = "无校验" Then
            parity = "N"
        ElseIf ComboBox3.Text = "奇校验" Then
            parity = "O"
        ElseIf ComboBox3.Text = "偶校验" Then
            parity = "E"
        End If
        comSetting = ComboBox2.Text & "," & parity & "," & ComboBox4.Text & "," & ComboBox5.Text
        '串口设置格式:9600,N,8,1
        AxMSComm1.Settings = comSetting
    End Sub
    '将十进制转换为16进制
    Private Function Decimal2Hex(ByRef c As String) As String
        Decimal2Hex = Hex(CInt(c))
        If Len(Decimal2Hex) < 2 Then
            Decimal2Hex = "0" & Decimal2Hex
        End If
    End Function
    '串口号发生改变的处理程序
    Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
        ChangePortProperty()
    End Sub
    Private ReadStr As String = ""
    Private Sub AxMSComm1_OnComm(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AxMSComm1.OnComm
        Dim i As Object
        Dim bytData As Object '用来从接收缓冲区读取数据
        Select Case AxMSComm1.CommEvent
            '对接收事件进行处理
            Case MSCommLib.OnCommConstants.comEvReceive
                bytData = AxMSComm1.Input '将接收到的数据暂存
                For i = 0 To UBound(bytData)
                    If CheckBox2.CheckState = CheckState.Checked Then
                        ReadStr = ReadStr & Decimal2Hex(CStr(bytData(i)))
                    Else
                        ReadStr = ReadStr & CStr(bytData(i))
                    End If
                Next
                TextBox2.Text = ReadStr '将转换后的数据在接收区显示
        End Select
    End Sub
End Class
五、程序中用到的几个函数解释:
Microsoft.VisualBasic.Strings.Right(String,Num):将字符串从右边开始截取字符串String中Num个字符。例如当String的值为“Welcome”,Num值为3,则该函数返回的值为字符串“ome”。另外通过将COM1拆分即可得到1,这是上例中得到得到串口号的方法。  
Val(String):将字符串类型转换为数值型。例如String为字符串“123”,则返回值为数值型123。
Hex(Integer):将整型数转换为16进制数。如:Integer为13,则返回十六进制的D
其实有些函数看不懂也没关系,可能我介绍的不是很详细,有些资料上网查一下也很方便的,这里就不再多罗嗦了。
说明:该上位机能够在运行时自动搜索计算机上可用的串口,适合入门者学习。但由于时间的关系,仓促之间写完本教程,仍有瑕疵,在此我不再进行优化了,望大家谅解。为方便大家学习,本教程及工程文件将会放到网盘与大家共享,并在此基础上增加一个例程,以方便大家理解上位机编写的方法。

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:114587 发表于 2018-1-17 20:47 | 只看该作者
网盘过期了 希望楼主不跟下~
回复

使用道具 举报

板凳
ID:86244 发表于 2019-4-18 23:30
网盘过期了 希望楼主不跟下~

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表