描述
上位機是指可以直接發出操控命令的計算機,一般是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。
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
‘開啟關閉串列埠程式碼
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 ’則開啟該串列埠
AxMSComm1.PortOpen = False ‘關閉該串列埠
’如下是訪問網站的連結的程式碼,可以選擇訪問網站的瀏覽器,這裡只使用預設的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
其實有些函式看不懂也沒關係,可能我介紹的不是很詳細,有些資料上網查一下也很方便的,這裡就不再多羅嗦了。