找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 9308|回復(fù): 1
上一主題 下一主題
收起左側(cè)

VB.NET上位機(jī)開發(fā)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:37685 發(fā)表于 2014-10-21 01:17 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
  說明:本文在編輯的時候,是直接從事先寫好的Word文檔中復(fù)制過來的,圖片都沒有粘貼過來,完整資料請上百度下載。上百度搜索“VB.NET上位機(jī)快速開發(fā)教程”即可,格式為PDF,上面有湖北文理學(xué)院的圖標(biāo)。在編寫此日志的時候,該文檔正在百度文庫和新浪愛問共享資料審核中,如無法搜到本文檔,請稍等片刻或者與本人聯(lián)系,我將通過郵箱發(fā)送。源碼下載地址在本文末尾可以看到!
一、準(zhǔn)備工作
一臺裝有VS2010的計算機(jī),用于測試的虛擬串口軟件。同時你必須具有VB基礎(chǔ)知識,這個VB上位機(jī)開發(fā)是入門級的,僅將VB.NET通信基礎(chǔ)方法稍作介紹。
二、串口通信常識
在串口通信中,通過編寫單片機(jī)程序知道,我們應(yīng)對如下參數(shù)進(jìn)行設(shè)置:波特率、數(shù)據(jù)位和停止位、奇偶校驗位。如果自己編寫上位機(jī)的時候,我們考慮的不能僅僅是這些了,下面介紹上位機(jī)開發(fā)過程中需要特別注意的知識點。
MSComm控件提供了兩種處理通信的方式:一種為事件驅(qū)動方式,該方式相當(dāng)于一般程序設(shè)計中的中斷方式。當(dāng)串口發(fā)生事件或錯誤時,MSComm控件會產(chǎn)生OnComm事件,用戶程序可以捕獲該事件進(jìn)行相應(yīng)處理。
常用屬性和方法     
利用MSComm控件實現(xiàn)計算機(jī)通信的關(guān)鍵是理解并正確設(shè)置MSComm控件眾多屬性和方法。以下是MSComm控件的常用屬性和方法:     
  ●Commport設(shè)置或返回串口號。其值從COM1到COM16。     
  ●Settings以字符串的形式設(shè)置或返回串口通信參數(shù)。     
  ●Portopen設(shè)置或返回串口狀態(tài)。     
  ●InputMode設(shè)置或返回接收數(shù)據(jù)的類型。有文本和二進(jìn)制兩種類型。     
  ●Inputlen設(shè)置或返回一次從接收緩沖區(qū)中讀取字節(jié)數(shù)。     
  ●InBufferSize設(shè)置或返回接收緩沖區(qū)的大小,缺省值為1024字節(jié)。     
  ●InBufferCount設(shè)置或返回接收緩沖區(qū)中等待計算機(jī)接收的字符數(shù)。
Input:從接收緩沖區(qū)中讀取數(shù)據(jù)并清空該緩沖區(qū),該屬性設(shè)計時無效,運行時只讀。
OutBufferSize設(shè)置或返回發(fā)送緩沖區(qū)的大小,缺省值為512字節(jié)。     
  ●OutBufferCount設(shè)置或返回發(fā)送緩沖區(qū)中等待計算機(jī)發(fā)送的字符數(shù)。     
  ●Output向發(fā)送緩沖區(qū)發(fā)送數(shù)據(jù),該屬性設(shè)計時無效,運行時只讀。     
  ●Rthreshold該屬性為一閥值。當(dāng)接收緩沖區(qū)中字符數(shù)達(dá)到該值時,MSComm控件設(shè)置Commevent屬性為ComEvReceive,并產(chǎn)生OnComm事件。用戶可在OnComm事件處理程序中進(jìn)行相應(yīng)處理。若Rthreshold屬性設(shè)置為0,則不產(chǎn)生OnComm事件。例如用戶希望接收緩沖區(qū)中達(dá)到一個字符就接收一個字符,可將Rthreshold設(shè)置為1。這樣接收緩沖區(qū)中接收到一個字符,就產(chǎn)生一次OnComm事件。     
  ●Sthreshold該屬性亦為一閥值。當(dāng)發(fā)送緩沖區(qū)中字符數(shù)小于該值時,MSComm控件設(shè)置Commevent屬性為ComEvSend,并產(chǎn)生OnComm事件。若Sthreshold屬性設(shè)置為0,則不產(chǎn)生OnComm事件。要特別注意的是僅當(dāng)發(fā)送緩沖區(qū)中字符數(shù)小于該值的瞬間才產(chǎn)生OnComm事件,其后就不再產(chǎn)生OnComm事件。例如Sthreshold設(shè)置為3,僅當(dāng)發(fā)送緩沖區(qū)中字符數(shù)從3降為2時,MSComm控件設(shè)置Commevent屬性為ComEvSend,同時產(chǎn)生OnComm事件,如發(fā)送緩沖區(qū)中字符始終為2,則不會再產(chǎn)生OnComm事件。這就避免了發(fā)送緩沖區(qū)中數(shù)據(jù)未發(fā)送完就反復(fù)發(fā)生OnComm事件。     
  ●CommEvent這是一個非常重要的屬性。該屬性設(shè)計時無效,運行時只讀。一旦串口發(fā)生通信事件或產(chǎn)生錯誤,依據(jù)產(chǎn)生的事件和錯誤,MSComm控件為CommEvent屬性賦不同的代碼,同時產(chǎn)生OnComm事件。用戶程序就可在OnComm事件處理程序中針對不同的代碼,進(jìn)行相應(yīng)的處理。
三、開發(fā)步驟(僅供參考)
1.     運行VS2010,新建一個Visual Basic的Windows窗體應(yīng)用程序項目。將窗體的StartPosition屬性改為CenterScreen,運行程序時,窗體在屏幕中央顯示。


  
2.     由于默認(rèn)情況下,通信所需的“Microsoft Communications Control,version 6.0”組件不在工具箱里面,所以我們需要手動添加。單擊左側(cè)的工具箱,并在控件欄單擊鼠標(biāo)右鍵,在彈出的菜單中選中“選擇項”,在彈出的對話框中單擊“COM組件”并選中“MicrosoftCommunications Control,version 6.0”,單擊確定即可完成添加。此時移動鼠標(biāo)到窗體上時,鼠標(biāo)箭頭就會變成電話的形狀,在窗體任意位置單擊放置該控件。

3.     單擊工具箱,在窗體上添加5個Label,并在屬性里將Text屬性依次改為:串口號、波特率、校驗、數(shù)據(jù)位、停止位。再向窗體上添加5個ComboBox,從上到下依次排列。
4.     向窗體添加一個OvalShape和一個Button。將OvalShape的size屬性改為“24,24”,F(xiàn)illStyle改為Solid。
5.     向窗體添加一個CheckBox、一個按鈕Button和一個TextBox,將CheckBox的Text屬性改為“十六進(jìn)制發(fā)送”將這個按鈕的text屬性改為“發(fā)送”。
6.     向窗體添加一個Label和一個TextBox。更改Label的Text屬性為“接收區(qū)”。
7.     向窗體添加一個CheckBox,將其Text屬性改為“十六進(jìn)制顯示”

下面將要對部分控件進(jìn)行設(shè)置,這樣可以減少代碼的長度
四、源代碼
Public Class Form1
    Dim cpSetting As String
    Dim com_last_num As Integer = 0   '定義一個全局變量,作用為記錄上一個串口號
    Sub GetSerialPortNames() '搜索計算機(jī)中所有可用串口函數(shù)
        On Error GoTo eRRHND '錯誤處理
        '搜索計算機(jī)中可用串口
        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
    '檢測串口是否可用函數(shù)
    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 '關(guān)閉串口
            Test_COM = True            '串口可用則返回
            Exit Function
Comm_Error:  '根據(jù)錯誤號作出相應(yīng)處理
            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 '接收緩沖區(qū)大小,此項無法在串口打開時進(jìn)行設(shè)置
        AxMSComm1.OutBufferSize = 1024 '發(fā)送緩沖區(qū)大小
        ComboBox2.Text = "9600"
        ComboBox3.Text = "無校驗"
        ComboBox4.Text = "8"
        ComboBox5.Text = "1"
        ChangePortProperty()
        '設(shè)置接收數(shù)據(jù)的格式為二進(jìn)制
        AxMSComm1.InputMode = MSCommLib.InputModeConstants.comInputModeBinary
        AxMSComm1.InputLen = 0 '設(shè)置從緩沖區(qū)讀取全部數(shù)據(jù)
        AxMSComm1.RThreshold = 1 '設(shè)置接收串口OnCommon事件
        AxMSComm1.PortOpen = True '打開串口
        If AxMSComm1.PortOpen = True Then
            OvalShape1.FillColor = Color.Green 'OvalShape顏色設(shè)為綠色
            Button1.Text = "關(guān)閉端口" '按鈕上的文字顯示為關(guān)閉端口
        Else
            OvalShape1.FillColor = Color.Red 'OvalShape顏色設(shè)為紅色
            Button1.Text = "打開端口" '按鈕上的文字顯示為打開端口
        End If
    End Sub
    '打開關(guān)閉串口代碼
    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 '如果串口是關(guān)閉的
            If Test_COM(ptNum) = True Then '如果選擇的串口可用?
                '     ChangePortProperty()
                AxMSComm1.PortOpen = True '則打開該串口
                Button1.Text = "關(guān)閉端口" '按鈕上的文字顯示為關(guān)閉端口
                OvalShape1.FillColor = Color.Green 'OvalShape顏色設(shè)為綠色
            End If
        Else
            AxMSComm1.PortOpen = False '關(guān)閉該串口
            OvalShape1.FillColor = Color.Red 'OvalShape顏色設(shè)為紅色
            Button1.Text = "打開端口" '按鈕上的文字顯示為打開端口
        End If
    End Sub
    '如下是訪問網(wǎng)站的鏈接的代碼,可以選擇訪問網(wǎng)站的瀏覽器,這里只使用默認(rèn)的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
    '處理發(fā)送數(shù)據(jù)的代碼
    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 '將要發(fā)送的數(shù)據(jù)存放到變量source_Txt中
        If CheckBox1.CheckState = CheckState.Checked Then '如果十六進(jìn)制發(fā)送復(fù)選框被勾上
            If Len(source_Txt) Mod 2 = 0 And Len(source_Txt) <> 0 Then '如果將要發(fā)送的數(shù)據(jù)長度不為或者能被2整除
                ReDim hexString(Len(source_Txt) / 2 - 1) '重新定義hexString數(shù)組
                For i = 0 To Len(source_Txt) - 1 Step 2
                    hexString(i / 2) = Val("&H" & Mid(source_Txt, i + 1, 2)) '將hexString轉(zhuǎn)換成十六進(jìn)制顯示
                Next
                AxMSComm1.Output = hexString '將轉(zhuǎn)換的數(shù)據(jù)發(fā)送到串口
            Else '否則提示格式不正確
                MsgBox("格式不正確!")
            End If
        Else '否則輸出字符串
            AxMSComm1.Output = TextBox1.Text
        End If
    End Sub
    Sub ChangePortProperty()
        Dim comSetting As String
        Dim parity As String = ""
        '關(guān)閉端口
        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
        '設(shè)置校驗方式
        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
        '串口設(shè)置格式:9600,N,8,1
        AxMSComm1.Settings = comSetting
    End Sub
    '將十進(jìn)制轉(zhuǎn)換為16進(jìn)制
    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
    '串口號發(fā)生改變的處理程序
    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 '用來從接收緩沖區(qū)讀取數(shù)據(jù)
        Select Case AxMSComm1.CommEvent
            '對接收事件進(jìn)行處理
            Case MSCommLib.OnCommConstants.comEvReceive
                bytData = AxMSComm1.Input '將接收到的數(shù)據(jù)暫存
                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 '將轉(zhuǎn)換后的數(shù)據(jù)在接收區(qū)顯示
        End Select
    End Sub
End Class
五、程序中用到的幾個函數(shù)解釋:
Microsoft.VisualBasic.Strings.Right(String,Num):將字符串從右邊開始截取字符串String中Num個字符。例如當(dāng)String的值為“Welcome”,Num值為3,則該函數(shù)返回的值為字符串“ome”。另外通過將COM1拆分即可得到1,這是上例中得到得到串口號的方法。  
Val(String):將字符串類型轉(zhuǎn)換為數(shù)值型。例如String為字符串“123”,則返回值為數(shù)值型123。
Hex(Integer):將整型數(shù)轉(zhuǎn)換為16進(jìn)制數(shù)。如:Integer為13,則返回十六進(jìn)制的D
其實有些函數(shù)看不懂也沒關(guān)系,可能我介紹的不是很詳細(xì),有些資料上網(wǎng)查一下也很方便的,這里就不再多羅嗦了。
說明:該上位機(jī)能夠在運行時自動搜索計算機(jī)上可用的串口,適合入門者學(xué)習(xí)。但由于時間的關(guān)系,倉促之間寫完本教程,仍有瑕疵,在此我不再進(jìn)行優(yōu)化了,望大家諒解。為方便大家學(xué)習(xí),本教程及工程文件將會放到網(wǎng)盤與大家共享,并在此基礎(chǔ)上增加一個例程,以方便大家理解上位機(jī)編寫的方法。

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:114587 發(fā)表于 2018-1-17 20:47 | 只看該作者
網(wǎng)盤過期了 希望樓主不跟下~
回復(fù)

使用道具 舉報

板凳
ID:86244 發(fā)表于 2019-4-18 23:30
網(wǎng)盤過期了 希望樓主不跟下~

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表