SerialPort類的用法與示例

轉:http://www.javashuo.com/article/p-aatagnys-gq.html

Microsoft .Net框架SerialPort類的用法與示例

從Microsoft .Net 2.0版本之後,就默認提供了System.IO.Ports.SerialPort類,用戶能夠很是簡單地編寫少許代碼就完成串口的信息收發程序。本文將介紹如何在PC端用C# .Net 來開發串口應用程序。html

1. 串口硬件信號定義

DB9 Connector 信號定義設計模式

Image 1

針腳
信號
定義
做用
1
DCD
載波檢測
Received Line Signal Detector(Data Carrier Detect)
2
RXD
接收數據
Received Data
3
TXD
發送數據
Transmit Data
4
DTR
數據終端準備好
Data Terminal Ready
5
SGND
信號地
Signal Ground
6
DSR
數據準備好
Data Set Ready
7
RTS
請求發送
Request To Send
8
CTS
清除發送
Clear To Send
9
RI
振鈴提示
Ring Indicator

2. 串口端口號搜索

一個最簡單的辦法:api

string[] portList = System.IO.Ports.SerialPort.GetPortNames();
for (int i = 0; i < portList.Length; i++)
{
    string name = portList[i];
    comboBox.Items.Add(name);
}

還有一種經過調用API的方法來獲取實現,能夠獲取詳細的完整串口名稱,對於USB-to-COM虛擬串口來講特別適用。數組

經過下面程序能夠獲取到與設備管理器中同樣的名字,例如「Prolific USB-to-Serial Comm Port(COM34)」, 而上面的方法只能獲取到「COM34」。緩存

複製代碼
/// <summary>
/// 枚舉win32 api
/// </summary>
public enum HardwareEnum
{
    // 硬件
    Win32_Processor, // CPU 處理器
    Win32_PhysicalMemory, // 物理內存條
    Win32_Keyboard, // 鍵盤
    Win32_PointingDevice, // 點輸入設備,包括鼠標。
    Win32_FloppyDrive, // 軟盤驅動器
    Win32_DiskDrive, // 硬盤驅動器
    Win32_CDROMDrive, // 光盤驅動器
    Win32_BaseBoard, // 主板
    Win32_BIOS, // BIOS 芯片
    Win32_ParallelPort, // 並口
    Win32_SerialPort, // 串口
    Win32_SerialPortConfiguration, // 串口配置
    Win32_SoundDevice, // 多媒體設置,通常指聲卡。
    Win32_SystemSlot, // 主板插槽 (ISA & PCI & AGP)
    Win32_USBController, // USB 控制器
    Win32_NetworkAdapter, // 網絡適配器
    Win32_NetworkAdapterConfiguration, // 網絡適配器設置
    Win32_Printer, // 打印機
    Win32_PrinterConfiguration, // 打印機設置
    Win32_PrintJob, // 打印機任務
    Win32_TCPIPPrinterPort, // 打印機端口
    Win32_POTSModem, // MODEM
    Win32_POTSModemToSerialPort, // MODEM 端口
    Win32_DesktopMonitor, // 顯示器
    Win32_DisplayConfiguration, // 顯卡
    Win32_DisplayControllerConfiguration, // 顯卡設置
    Win32_VideoController, // 顯卡細節。
    Win32_VideoSettings, // 顯卡支持的顯示模式。

    // 操做系統
    Win32_TimeZone, // 時區
    Win32_SystemDriver, // 驅動程序
    Win32_DiskPartition, // 磁盤分區
    Win32_LogicalDisk, // 邏輯磁盤
    Win32_LogicalDiskToPartition, // 邏輯磁盤所在分區及始末位置。
    Win32_LogicalMemoryConfiguration, // 邏輯內存配置
    Win32_PageFile, // 系統頁文件信息
    Win32_PageFileSetting, // 頁文件設置
    Win32_BootConfiguration, // 系統啓動配置
    Win32_ComputerSystem, // 計算機信息簡要
    Win32_OperatingSystem, // 操做系統信息
    Win32_StartupCommand, // 系統自動啓動程序
    Win32_Service, // 系統安裝的服務
    Win32_Group, // 系統管理組
    Win32_GroupUser, // 系統組賬號
    Win32_UserAccount, // 用戶賬號
    Win32_Process, // 系統進程
    Win32_Thread, // 系統線程
    Win32_Share, // 共享
    Win32_NetworkClient, // 已安裝的網絡客戶端
    Win32_NetworkProtocol, // 已安裝的網絡協議
    Win32_PnPEntity,//all device
}

/// <summary>
/// WMI取硬件信息
/// </summary>
/// <param name="hardType"></param>
/// <param name="propKey"></param>
/// <returns></returns>
public static string[] MulGetHardwareInfo(HardwareEnum hardType, string propKey)
{
    List<string> strs = new List<string>();
    try
    {
        using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from " + hardType))
        {
            var hardInfos = searcher.Get();
            foreach (var hardInfo in hardInfos)
            {
                if (hardInfo.Properties[propKey].Value.ToString().Contains("COM"))
                {
                    strs.Add(hardInfo.Properties[propKey].Value.ToString());
                }
            }
            searcher.Dispose();
        }
        return strs.ToArray();
    }
    catch
    {
        return null;
    }
    finally
    { strs = null; }
}

//經過WMI獲取COM端口
string[] portList = MulGetHardwareInfo(HardwareEnum.Win32_PnPEntity, "Name");
複製代碼

3. 串口屬性參數設置

參見MSDN上的幫助文件,SerialPort類所包含的屬性詳見下表。網絡

  名稱 說明
System_CAPS_pubproperty BaseStream

獲取 Stream 對象的基礎 SerialPort 對象。app

System_CAPS_pubproperty BaudRate

獲取或設置串行波特率。框架

System_CAPS_pubproperty BreakState

獲取或設置中斷信號狀態。ide

System_CAPS_pubproperty BytesToRead

獲取接收緩衝區中數據的字節數。oop

System_CAPS_pubproperty BytesToWrite

獲取發送緩衝區中數據的字節數。

System_CAPS_protproperty CanRaiseEvents

獲取一個值,該值指示組件是否能夠引起一個事件。(繼承自 Component。)

System_CAPS_pubproperty CDHolding

獲取端口的載波檢測行的狀態。

System_CAPS_pubproperty Container

獲取 IContainer ,其中包含 Component。(繼承自 Component。)

System_CAPS_pubproperty CtsHolding

獲取「能夠發送」行的狀態。

System_CAPS_pubproperty DataBits

獲取或設置每一個字節的標準數據位長度。

System_CAPS_protproperty DesignMode

獲取一個值,該值指示是否 Component 當前處於設計模式。(繼承自 Component。)

System_CAPS_pubproperty DiscardNull

獲取或設置一個值,該值指示 null 字節在端口和接收緩衝區之間傳輸時是否被忽略。

System_CAPS_pubproperty DsrHolding

獲取數據設置就緒 (DSR) 信號的狀態。

System_CAPS_pubproperty DtrEnable

獲取或設置一個值,該值在串行通訊過程當中啓用數據終端就緒 (DTR) 信號。

System_CAPS_pubproperty Encoding

獲取或設置傳輸先後文本轉換的字節編碼。

System_CAPS_protproperty Events

獲取的事件處理程序附加到此列表 Component。(繼承自 Component。)

System_CAPS_pubproperty Handshake

使用 Handshake 中的值獲取或設置串行端口數據傳輸的握手協議。

System_CAPS_pubproperty IsOpen

獲取一個值,該值指示 SerialPort 對象的打開或關閉狀態。

System_CAPS_pubproperty NewLine

獲取或設置用於解釋 ReadLine 和 WriteLine 方法調用結束的值。

System_CAPS_pubproperty Parity

獲取或設置奇偶校驗檢查協議。

System_CAPS_pubproperty ParityReplace

獲取或設置一個字節,該字節在發生奇偶校驗錯誤時替換數據流中的無效字節。

System_CAPS_pubproperty PortName

獲取或設置通訊端口,包括但不限於全部可用的 COM 端口。

System_CAPS_pubproperty ReadBufferSize

獲取或設置 SerialPort 輸入緩衝區的大小。

System_CAPS_pubproperty ReadTimeout

獲取或設置讀取操做未完成時發生超時以前的毫秒數。

System_CAPS_pubproperty ReceivedBytesThreshold

獲取或設置 DataReceived 事件發生前內部輸入緩衝區中的字節數。

System_CAPS_pubproperty RtsEnable

獲取或設置一個值,該值指示在串行通訊中是否啓用請求發送 (RTS) 信號。

System_CAPS_pubproperty Site

獲取或設置 ISite 的 Component。(繼承自 Component。)

System_CAPS_pubproperty StopBits

獲取或設置每一個字節的標準中止位數。

System_CAPS_pubproperty WriteBufferSize

獲取或設置串行端口輸出緩衝區的大小。

System_CAPS_pubproperty WriteTimeout

獲取或設置寫入操做未完成時發生超時以前的毫秒數。

簡單初始化串口參數的示例程序:

複製代碼
SerialPort mySerialPort = new SerialPort("COM2");
mySerialPort.BaudRate = 9600;
mySerialPort.Parity=Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.Non;

mySerialPort.DataReceived += new SerialDataReceivedEvenHandler(DataReceive_Method);

mySerialPort.Open();
複製代碼

4. 串口發送信息

SerialPort類定義了多種方法用於串口發送信息。

Write(Byte[], Int32, Int32)    使用緩衝區中的數據將指定數量的字節寫入串行端口
Write(Char[], Int32, Int32)    使用緩衝區中的數據將指定數量的字符寫入串行端口
Write(String)    將指定的字符串寫入串行端口
WriteLine(String)    將指定的字符串和NewLine值寫入輸出緩衝區

下面是一個簡單的例子說明如何經過串口發送字符串和字節數據:

複製代碼
using System.IO.Ports;

private static void SendSampleData()
{
    // Instantiate the communications
    // port with some basic settings
    SerialPort port = new SerialPort(
        "COM1", 9600, Parity.None, 8, StopBits.One);

    // Open the port for communications
    port.Open();

    // Write a string
    port.Write("Hello World");

    // Write a set of bytes
    port.Write(new byte[] { 0x0A, 0xE2, 0xFF }, 0, 3);

    // Close the port
    port.Close();
}
複製代碼

下面是如何發送一個文本文件的例子:

private static void SendTextFile(SerialPort port, string FileName)
{
    port.Write(File.OpenText(FileName).ReadToEnd());
}

下面是如何發送一個二進制文件的例子:

private static void SendBinaryFile(SerialPort port, string FileName)
{
    using (FileStream fs = File.OpenRead(FileName))
        port.Write((new BinaryReader(fs)).ReadBytes((int)fs.Length), 0, (int)fs.Length);
}

5. 串口接收信息

SerialPort類定義了多種方法用於串口接收信息。

Read(Byte[], Int32, Int32)     從SerialPort輸入緩衝區讀取一些字節,並將那些字節寫入字節數組中指定的偏移量處
Read(Byte[], Int32, Int32)     從SerialPort輸入緩衝區讀取一些字符,並將那些字符寫入字符數組中指定的偏移量處
ReadByte()    從SerialPort輸入緩衝區中同步讀取一個字節
ReadChar()    從SerialPort輸入緩衝區中同步讀取一個字符
ReadExisting()    在編碼的基礎上,讀取SerialPort對象的流和輸入緩衝區中全部當即可用的字節
ReadLine()    一直讀取到輸入緩衝區中的NewLine值
ReadTo(String)    一直讀取到輸入緩衝區中的指定value的字符串

一般一個比較常見的用法就是將串口裏面當即能用的字符或數據讀取而後打印在textbox等控件中顯示。

複製代碼
#region Namespace Inclusions
using System;
using System.IO.Ports;
using System.Windows.Forms;
#endregion

namespace SerialPortExample
{
    class SerialPortProgram
    {
        // Create the serial port with basic settings
        private SerialPort port = new SerialPort("COM1",
          9600, Parity.None, 8, StopBits.One);

        [STAThread]
        static void Main(string[] args)
        {
            // Instatiate this class
            new SerialPortProgram();
        }

        private SerialPortProgram()
        {
            Console.WriteLine("Incoming Data:");

            // Attach a method to be called when there
            // is data waiting in the port's buffer
            port.DataReceived += new
              SerialDataReceivedEventHandler(port_DataReceived);

            // Begin communications
            port.Open();

            // Enter an application loop to keep this thread alive
            Application.Run();
        }

        private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            // Show all the incoming data in the port's buffer
            Console.WriteLine(port.ReadExisting());
        }
    }
}
複製代碼

另外還有一種應用場合是須要緩存一段串口接收數據,而後在緩存數據中查找有用信息,這時能夠採用下面例子所用的辦法。

複製代碼
using System;
using System.IO.Ports;
using System.Collections.Generic;

namespace SerialComBuffering
{
    class Program
    {
        SerialPort com = new SerialPort(SerialPort.GetPortNames()[0],
          9600, Parity.None, 8, StopBits.One);

        List<byte> bBuffer = new List<byte>();
        string sBuffer = String.Empty;

        static void Main(string[] args)
        { new Program(); }

        Program()
        {
            com.DataReceived += new SerialDataReceivedEventHandler(com_DataReceived);

            com.Open();

            Console.WriteLine("Waiting for incoming data...");

            Console.ReadKey();
        }

        void com_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            // Use either the binary OR the string technique (but not both)
            // Buffer and process binary data
            while (com.BytesToRead > 0)
                bBuffer.Add((byte)com.ReadByte());
            ProcessBuffer(bBuffer);

            // Buffer string data
            sBuffer += com.ReadExisting();
            ProcessBuffer(sBuffer);
        }

        private void ProcessBuffer(string sBuffer)
        {
            // Look in the string for useful information
            // then remove the useful data from the buffer
        }

        private void ProcessBuffer(List<byte> bBuffer)
        {
            // Look in the byte array for useful information
            // then remove the useful data from the buffer
        }
    }
}
複製代碼
相關文章
相關標籤/搜索