C#串口serialPort操作

來源:互聯網
上載者:User

 

現在大多數硬體裝置均採用串口技術與電腦相連,因此串口的應用程式開發越來越普遍。例如,在電腦沒有安裝網卡的情況下,將本機上的一些資訊資料轉送到另一台電腦上,那麼利用串口通訊就可以實現。運行本程式,在“發送資料”文字框中輸入要傳送的資料,單擊【發送】按鈕,將傳送的資料發送到所選擇的連接埠號碼中;單擊【接收】按鈕,傳遞的資料被接收到“接收資料”文字框中。13.1所示。

技術要點

在.NET Framework 2.0中提供了SerialPort類,該類主要實現串口資料通訊等。下面主要介紹該類的主要屬性(表13.1)和方法(表13.2)。

表13.1                                                      SerialPort類的常用屬性

 

名  稱

 

說  明

 

BaseStream

 

擷取 SerialPort 對象的基礎 Stream 對象

 

BaudRate

 

擷取或設定串列傳輸速率

 

BreakState

 

擷取或設定中斷訊號狀態

 

BytesToRead

 

擷取接收緩衝區中資料的位元組數

 

BytesToWrite

 

擷取發送緩衝區中資料的位元組數

 

CDHolding

 

擷取連接埠的偵測載波行的狀態

 

CtsHolding

 

擷取“可以發送”行的狀態

 

DataBits

 

擷取或設定每個位元組的標準資料位元長度

 

DiscardNull

 

擷取或設定一個值,該值指示 Null 位元組在連接埠和接收緩衝區之間傳輸時是否被忽略

 

DsrHolding

 

擷取資料設定就緒 (DSR) 訊號的狀態

 

DtrEnable

 

擷取或設定一個值,該值在串列通訊過程中啟用資料終端機就緒 (DTR) 訊號

 

Encoding

 

擷取或設定傳輸前後文本轉換的位元組編碼

 

Handshake

 

擷取或設定序列埠資料轉送的握手協議

 

IsOpen

 

擷取一個值,該值指示 SerialPort 對象的開啟或關閉狀態

 

NewLine

 

擷取或設定用於解釋 ReadLine( )和WriteLine( )方法調用結束的值

 

Parity

 

擷取或設定同位檢查協議

續表

 

名  稱

 

說  明

 

ParityReplace

 

擷取或設定一個位元組,該位元組在發生同位錯誤時替換資料流中的無效位元組

 

PortName

 

擷取或設定通訊連接埠,包括但不限於所有可用的 COM 連接埠

 

ReadBufferSize

 

擷取或設定 SerialPort 輸入緩衝區的大小

 

ReadTimeout

 

擷取或設定讀取操作未完成時發生逾時之前的毫秒數

 

ReceivedBytesThreshold

 

擷取或設定 DataReceived 事件發生前內部輸入緩衝區中的位元組數

 

RtsEnable

 

擷取或設定一個值,該值指示在串列通訊中是否啟用請求發送 (RTS) 訊號

 

StopBits

 

擷取或設定每個位元組的標準停止位元

 

WriteBufferSize

 

擷取或設定序列埠輸出緩衝區的大小

 

WriteTimeout

 

擷取或設定寫入操作未完成時發生逾時之前的毫秒數

表13.2                                                     SerialPort類的常用方法

 

方 法 名 稱

 

說  明

 

Close

 

關閉連接埠串連,將 IsOpen 屬性設定為False,並釋放內部 Stream 對象

 

Open

 

開啟一個新的序列埠串連

 

Read

 

從 SerialPort 輸入緩衝區中讀取

 

ReadByte

 

從 SerialPort 輸入緩衝區中同步讀取一個位元組

 

ReadChar

 

從 SerialPort 輸入緩衝區中同步讀取一個字元

 

ReadLine

 

一直讀取到輸入緩衝區中的 NewLine 值

 

ReadTo

 

一直讀取到輸入緩衝區中指定 value 的字串

 

Write

 

已重載。將資料寫入序列埠輸出緩衝區

 

WriteLine

 

將指定的字串和 NewLine 值寫入輸出緩衝區

注意:用跳線使串口的第2、3針串連,可以在本機電腦上實現串口通訊,所以,通過串口的第2、3針的串連可以對程式進行檢測。串口截面圖13.2所示。

圖13.2 串口截面圖

實現過程

(1)建立一個項目,命名為Ex13_01,預設表單為Form1。

(2)在Form1表單中,主要添加兩個Button控制項,分別用於執行發送資料和接受資料,添加兩個TextBox控制項,用於輸入發送資料和顯示接收資料。

(3)主要程式碼。

         private void button1_Click(object sender, EventArgs e)

         {

             serialPort1.PortName = "COM1";

             serialPort1.BaudRate = 9600;

             serialPort1.Open();

             byte[] data = Encoding.Unicode.GetBytes(textBox1.Text);

             string str = Convert.ToBase64String(data);

             serialPort1.WriteLine(str);

             MessageBox.Show("資料發送成功!","系統提示");

         }

         private void button2_Click(object sender, EventArgs e)

         {

             byte[] data = Convert.FromBase64String(serialPort1.ReadLine());

             textBox2.Text = Encoding.Unicode.GetString(data);

             serialPort1.Close();

             MessageBox.Show("資料接收成功!","系統提示");

         }

舉一反三

根據本執行個體,讀者可以實現以下功能。

遠程監控對方電腦螢幕。

    下位機控製程序。

執行個體419 通過串口關閉對方電腦

執行個體說明

在網路應用程式中,主要通過網卡實現資料的傳輸,因此可以利用通訊端技術實現遠程關閉電腦。如果電腦中沒有安裝網卡,該如何?遠程關閉電腦呢?本例實現了利用串口關閉對方電腦,程式運行結果13.3所示。

技術要點

本執行個體使用SerialPort類的屬性和方法,請參見執行個體“通過串口發送資料”。下面主要介紹SerialPort類的DataReceived 事件,DataReceived事件為本執行個體的主要使用技術。DataReceived事件表示將處理 SerialPort 對象的資料接收事件的方法。串列接收事件可以由SerialData 枚舉中的任何項引起,是否引發此事件由作業系統決定,所以不一定會報告所有同位錯誤。

注意:本執行個體從開發到測試,都是由本機電腦完成的,使用者只需要使用跳線將串口的第2、3針串連,可以在本機電腦上實現串口通訊。跳線串連請參見圖13.2。

實現過程

(1)建立一個項目,命名為Ex13_02,預設表單為Form1。

(2)在Form1表單中,主要添加兩個Button控制項,分別用於開啟通訊串口和關閉對方電腦。

(3)主要程式碼。

         private void button1_Click(object sender, EventArgs e)

         {

             //開啟串口

             serialPort1.PortName = "COM1";

             serialPort1.Open();

             button1.Enabled = false;

             button2.Enabled = true;

         }    //資料接收事件,等待接收關機命令

         private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)

         {

             byte[] data = Convert.FromBase64String(serialPort1.ReadLine());

             string str = Encoding.Unicode.GetString(data);

             serialPort1.Close();

             if (str == "關機")

             {

                 Process p = new Process();

                 p.StartInfo.FileName = "cmd.exe";

                 p.StartInfo.UseShellExecute = false;

                 p.StartInfo.RedirectStandardInput = true;

                 p.StartInfo.RedirectStandardOutput = true;

                  p.StartInfo.RedirectStandardError = true;

                 p.StartInfo.CreateNoWindow = true;

                 p.Start();

                 p.StandardInput.WriteLine("shutdown /s");

                 p.StandardInput.WriteLine("exit");

             }

         } //發送關機命令

         private void button2_Click(object sender, EventArgs e)

         {

             if (button2.Text == "關閉電腦")

             {

                 //發送關機命令資料

                 byte[] data = Encoding.Unicode.GetBytes("關機");

                 string str = Convert.ToBase64String(data);

                 serialPort1.WriteLine(str);

                 button2.Text = "取消關機";

             }

             else

             {

                 button2.Text = "關閉電腦";

                 button1.Enabled = true;

                 button2.Enabled = false;

                 //取消關機

                 Process p = new Process();

                 p.StartInfo.FileName = "cmd.exe";

                 p.StartInfo.UseShellExecute = false;

                 p.StartInfo.RedirectStandardInput = true;

                  p.StartInfo.RedirectStandardOutput = true;

                 p.StartInfo.RedirectStandardError = true;

                 p.StartInfo.CreateNoWindow = true;

                 p.Start();

                 p.StandardInput.WriteLine("shutdown /a");

                  p.StandardInput.WriteLine("exit");

             }

         }

在我的測試軟體中發現一個問題,就是當發送資料小於或等於8位時,一切正常,如果大於8為位元組,則在datareceived事件中接收到的資料會分成兩段,第一段為8位,第二段為剩下的位元組,很奇怪,在msdn中講到不能保證每次發送的資料都能正確接收到,需要參照BytesToRead屬性來確定要讀取的資料量,所以我想出來的解決辦法為:

int DataLength=serialPort.BytesToRead;

int i=0;

StringBuilder sb=new StringBuilder();

while(i<DataLength)

{

    byte[] ds=new byte[1024];

    int len=serialPort.Read(ds,0,1024);

    sb.Append(Encoding.Ascii.GetString(ds,0,len));

    i+=len;

}

Console.Write(sb,ToString());

這種奇怪的方法可以解決問題,後來想想應該是串口的工作方式決定的也有可能,期待其他的解決方

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.