來從最簡單的程式碼開始着手,沒意外的話應該不會有太多的例外狀況把自己弄糊塗,就發送,管他三七二十一個送,有沒有人接資料,再說吧!
來從最簡單的程式碼開始着手,沒意外的話應該不會有太多的例外狀況把自己弄糊塗,就發送,管他三七二十一個送,有沒有人接資料,再說吧!
左方的流程圖在表示一個最簡單的發送行為,開啟 –> 發送 –> 關閉,然後就結束了。 這篇文的主要大概就是說明 (1) SerialPort.Open 方法 (2) SerialPort.IsOpen 屬性 (3) SerialPort.Write 方法 (Byte[], Int32, Int32) (4) SerialPort.Close 方法 夠簡單了吧! |
一般你會看到的範例
大部份你會看到這樣的範例程式碼:
Public Class Form1 Private comport As SerialPort Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click comport = New SerialPort("COM4", 9600, Parity.None, 8, StopBits.One) Dim buffer(0) As Byte buffer(0) = 1 If comport.IsOpen = False Then comport.Open() End If comport.Write(buffer, 0, buffer.Length) comport.Close() End Sub End Class
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
SerialPort comport;
private void button1_Click(object sender, EventArgs e)
{
comport = new SerialPort("COM4", 9600, Parity.None, 8, StopBits.One);
Byte[] buffer = new Byte[1];
buffer[0] = 1;
if (!comport.IsOpen)
{
comport.Open();
}
comport.Write(buffer, 0, buffer.Length);
comport.Close();
}
}
先從這個通用性的範例來說明,首先我們把comport這個變數宣告在類別的全域中,放在全域是有用處的,以後在聊到事件的時候會再加以說明,剩下的東西通通交給Button1 (button1) 的 Click事件委派函式。
(1) 先建立 SerailPort 類別的執行個體並將它指派給comport變數。
(2) 建立一個Byte型別的陣列,我們的例子很簡單就送一個Byte,值也固定為1;這邊要注意的是 Visual Basic 和 C# 宣告陣列大小的用法不同,Visual Basic 宣告的是上限,而 C# 宣告的是個數。
(3) 使用SerialPort.IsOpen屬性來判斷序列埠是否有被開啟,如果沒有的話則使用SerialPort.Open方法來開啟序列埠。
(3-1) SerialPort.IsOpen屬性其實只有指示特定執行個體中IsOpen屬性值,它和實際的序列埠沒有關係,它只是當這個執行個體執行SerialPort.Open方法執行成功會將這個值改變為True,而當SerialPort.Close方法執行成功時會改變為Fasle,以下列的程式碼來示範,我使用了兩個變數個別指向兩個SerialPort執行個體,而指定的序列埠都是COM4,雖然comport1已經將COM4開啟了,但comport2.IsOpen的屬性依然是False,也就是說這個屬性並不是真的去偵測該序列埠是否真的被開啟,而只是一個內部的變數記錄而已。
Public Class Form1
Private comport1 As SerialPort
Private comport2 As SerialPort
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
comport1 = New SerialPort("COM4", 9600, Parity.None, 8, StopBits.One)
comport2 = New SerialPort("COM4", 9600, Parity.None, 8, StopBits.One)
comport1.Open()
MessageBox.Show(comport2.IsOpen.ToString())
End Sub
End Class
(3-2) 當我們在產生執行個體的時候如果指定了不存在或已經被開啟的序列埠並不會產生例外,此種例外情形的會在呼叫SerialPort.Open方法時產生,假設我們寫了以下的程式碼:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private SerialPort comport1;
private SerialPort comport2;
private void button1_Click(object sender, EventArgs e)
{
comport1 = new SerialPort("COM4", 9600, Parity.None, 8, StopBits.One);
comport2 = new SerialPort("COM4", 9600, Parity.None, 8, StopBits.One);
Open(comport1);
Open(comport2);
}
private void Open(SerialPort comport)
{
if (!comport.IsOpen)
{
comport.Open();
}
}
}
上述程式碼一旦執行後就會產生以下的錯誤 (請先Click button):
(4) 當SerialPort已經開啟以後就使用SerialPort.Write 方法 (Byte[], Int32, Int32)將前面的Byte陣列送出去,這個方法的參數1是你所要傳送的資料、參數二是你要從這個陣列的哪個位置開始送,參數三則是你要送的資料有多長。comport.Write(buffer, 0, buffer.Length) 這個寫法就是代表要送的資料存在buffer這個陣列中;從陣列的第一個元素 (它的Index是0);整個buffer我都要送,所以直接用buffer.Length,要多長就多長這樣。
(5) 發送結束後呼叫SerialPort.Close方法將序列埠關閉。
為什麼會加註這是一般型範例,因為我並不建議這麼寫,但覺得想要讓大家看到一個軌跡才能瞭解到為什麼我會用另一種寫法,這系列文會是一個長期抗戰,會有許多架構演變的足跡,下一篇依然會用到這個純發送的方式但換個寫法,這篇介紹的內容就先當暖身操。