說明:本文在編輯的時候,是直接從事先寫好的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 其實有些函數看不懂也沒關系,可能我介紹的不是很詳細,有些資料上網查一下也很方便的,這里就不再多羅嗦了。 說明:該上位機能夠在運行時自動搜索計算機上可用的串口,適合入門者學習。但由于時間的關系,倉促之間寫完本教程,仍有瑕疵,在此我不再進行優化了,望大家諒解。為方便大家學習,本教程及工程文件將會放到網盤與大家共享,并在此基礎上增加一個例程,以方便大家理解上位機編寫的方法。
|