上位機是指可以直接發出操控命令的計算機,一般是PC/host computer/master computer/upper computer,屏幕上顯示各種信號變化(液壓,水位,溫度等)。下位機是直接控制設備獲取設備狀況的計算機,一般是PLC/單片機single chip microcomputer/slave computer/lower computer之類的。上位機發出的命令首先給下位機,下位機再根據此命令解釋成相應時序信號直接控制相應設備。下位機不時讀取設備狀態數據(一般為模擬量),轉換成數字信號反饋給上位機。簡言之如此,實際情況千差萬別,但萬變不離其宗:上下位機都需要編程,都有專門的開發系統。
上位機工作原理
兩機如何通訊,一般取決于下位機,TCP/IP一般是支持的,但是下位機一般具有更可靠的獨有通訊協議,購買下位機時,會帶一大堆手冊光盤,告訴你如何使用特有協議通訊,里面會舉大量例子,一般對編程人員而言一看也就那么回事,使用一些新的API(API(Application Programming Interface,應用程序編程接口)是一些預先定義的函數,目的是提供應用程序與開發人員基于某軟件或硬件的以訪問一組例程的能力,而又無需訪問源碼,或理解內部工作機制的細節罷了,多語言支持功能模塊,一般同時支持數種高級語言為上位機編程。
通常上位機和下位機通訊可以采用不同的上位機示例圖片通訊協議,可以有RS232的串口通訊或者采用RS485串行通訊。當用計算機和PLC通訊的時候,不但可以采用傳統的D形式的串行通訊,還可以采用更適合工業控制的雙線的PROFIBUS-DP通訊。采用封裝好的程序開發工具就可以實現PLC和上位機的通訊,當然可以自己編寫驅動類的接口協議控制上位機和下位機的通訊。
通常工控機,工作站,觸摸屏作為上位機,通信控制PLC,單片機等作為下位機,從而控制相關設備元件和驅動裝置。
上位機開發的軟件
1、visual studio 2008
Microsoft Visual Studio 2008是面向Windows Vista、Office 2007、Web 2.0的下一代開發工具,代號“Orcas”,是對Visual Studio 2005的一次及時、全面的升級。
VS2008引入了250多個新特性,整合了對象、關系型數據、XML的訪問方式,語言更加簡潔。使用Visual Studio 2008可以高效開發Windows應用程序。設計器中可以實時反映變更,XAML中智能感知功能可以提高開發效率。同時Visual Studio 2008支持項目模板、調試器和部署程序。Visual Studio 2008可以高效開發Web應用,集成了AJAX 1.0,包含AJAX項目模板,它還可以高效開發Office應用和Mobile應用。
2、MFC
是微軟公司提供的一個類庫(class libraries),以C++類的形式封裝了Windows API,并且包含一個應用程序框架,以減少應用程序開發人員的工作量。其中包含大量Windows句柄封裝類和很多Windows的內建控件和組件的封裝類。
3、Qt
Qt[1] 是一個1991年由Qt Company開發的跨平臺C++圖形用戶界面應用程序開發框架。它既可以開發GUI程序,也可用于開發非GUI程序,比如控制臺工具和服務器。Qt是面向對象的框架,使用特殊的代碼生成擴展(稱為元對象編譯器(Meta Object Compiler, moc))以及一些宏,Qt很容易擴展,并且允許真正地組件編程。2008年,Qt Company科技被諾基亞公司收購,Qt也因此成為諾基亞旗下的編程語言工具。
4、GTK
GTK+(GIMP Toolkit)是一套源碼以LGPL許可協議分發、跨平臺的圖形工具包。最初是為GIMP寫的,已成為一個功能強大、設計靈活的一個通用圖形庫,是GNU/Linux下開發圖形界面的應用程序的主流開發工具之一。并且,GTK+也有Windows版本和Mac OS X版。
5、wxWidgets
wxWidgets是一個開源的跨平臺的C++構架庫(framework),它可以提供GUI(圖形用戶界面)和其它工具。目前的2.x版本支持所有版本的Windows、帶GTK+或Motif的Unix和MacOS。一個支持OS/2的版本正在開發中。開源跨平臺, 和 CodeBlocks (開源跨平臺的IDE)配合的很好, 而且可以用 wxSmith 很方便的設計界面。 而且學過MFC上手 wxWidgets 很快。
上位機快速開發教程
(1)準備工作
一臺裝有VS2010的計算機,用于測試的虛擬串口軟件。同時你必須具有VB基礎知識,這個VB上位機開發是入門級的,僅將VB.NET通信基礎方法稍作介紹。
(2)串口通信常識
在串口通信中,通過編寫單片機程序知道,我們應對如下參數進行設置:波特率、數據位和停止位、奇偶校驗位。如果自己編寫上位機的時候,我們考慮的不能僅僅是這些了,下面介紹上位機開發過程中需要特別注意的知識點。
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事件處理程序中針對不同的代碼,進行相應的處理。
(3)開發步驟(僅供參考)
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屬性改為“十六進制顯示”
下面將要對部分控件進行設置,這樣可以減少代碼的長度 將波特率一欄ComboBox的Item屬性中添加如下內容:
將校驗一欄ComboBox的Item屬性中添加如下內容
將數據位一欄ComboBox的Item屬性中添加如下內容
將波特率一欄ComboBox的Item屬性中添加如下內容
四、源代碼
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
其實有些函數看不懂也沒關系,可能我介紹的不是很詳細,有些資料上網查一下也很方便的,這里就不再多羅嗦了。
評論