[C#] Microsoft .Net框架SerialPort类的用法与示例(文件发)

C# 同时被 2 个专栏收录
63 篇文章 0 订阅
86 篇文章 1 订阅

https://www.cnblogs.com/hwBeta/p/6926363.html

从Microsoft .Net 2.0版本以后,就默认提供了System.IO.Ports.SerialPort类,用户可以非常简单地编写少量代码就完成串口的信息收发程序。本文将介绍如何在PC端用C# .Net 来开发串口应用程序。

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. 串口端口号搜索

一个最简单的办法:

复制代码
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, // 显卡支持的显示模式。
</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 操作系统</span>
Win32_TimeZone, <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 时区</span>
Win32_SystemDriver, <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 驱动程序</span>
Win32_DiskPartition, <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 磁盘分区</span>
Win32_LogicalDisk, <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 逻辑磁盘</span>
Win32_LogicalDiskToPartition, <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 逻辑磁盘所在分区及始末位置。</span>
Win32_LogicalMemoryConfiguration, <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 逻辑内存配置</span>
Win32_PageFile, <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 系统页文件信息</span>
Win32_PageFileSetting, <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 页文件设置</span>
Win32_BootConfiguration, <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 系统启动配置</span>
Win32_ComputerSystem, <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 计算机信息简要</span>
Win32_OperatingSystem, <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 操作系统信息</span>
Win32_StartupCommand, <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 系统自动启动程序</span>
Win32_Service, <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 系统安装的服务</span>
Win32_Group, <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 系统管理组</span>
Win32_GroupUser, <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 系统组帐号</span>
Win32_UserAccount, <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 用户帐号</span>
Win32_Process, <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 系统进程</span>
Win32_Thread, <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 系统线程</span>
Win32_Share, <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 共享</span>
Win32_NetworkClient, <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 已安装的网络客户端</span>
Win32_NetworkProtocol, <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 已安装的网络协议</span>
Win32_PnPEntity,<span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">all device</span>

}

/// <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_pubpropertyBaseStream

获取 Stream 对象的基础 SerialPort 对象。

System_CAPS_pubpropertyBaudRate

获取或设置串行波特率。

System_CAPS_pubpropertyBreakState

获取或设置中断信号状态。

System_CAPS_pubpropertyBytesToRead

获取接收缓冲区中数据的字节数。

System_CAPS_pubpropertyBytesToWrite

获取发送缓冲区中数据的字节数。

System_CAPS_protpropertyCanRaiseEvents

获取一个值,该值指示组件是否可以引发一个事件。(继承自 Component。)

System_CAPS_pubpropertyCDHolding

获取端口的载波检测行的状态。

System_CAPS_pubpropertyContainer

获取 IContainer ,其中包含 Component。(继承自 Component。)

System_CAPS_pubpropertyCtsHolding

获取“可以发送”行的状态。

System_CAPS_pubpropertyDataBits

获取或设置每个字节的标准数据位长度。

System_CAPS_protpropertyDesignMode

获取一个值,该值指示是否 Component 当前处于设计模式。(继承自 Component。)

System_CAPS_pubpropertyDiscardNull

获取或设置一个值,该值指示 null 字节在端口和接收缓冲区之间传输时是否被忽略。

System_CAPS_pubpropertyDsrHolding

获取数据设置就绪 (DSR) 信号的状态。

System_CAPS_pubpropertyDtrEnable

获取或设置一个值,该值在串行通信过程中启用数据终端就绪 (DTR) 信号。

System_CAPS_pubpropertyEncoding

获取或设置传输前后文本转换的字节编码。

System_CAPS_protpropertyEvents

获取的事件处理程序附加到此列表 Component。(继承自 Component。)

System_CAPS_pubpropertyHandshake

使用 Handshake 中的值获取或设置串行端口数据传输的握手协议。

System_CAPS_pubpropertyIsOpen

获取一个值,该值指示 SerialPort 对象的打开或关闭状态。

System_CAPS_pubpropertyNewLine

获取或设置用于解释 ReadLine  WriteLine 方法调用结束的值。

System_CAPS_pubpropertyParity

获取或设置奇偶校验检查协议。

System_CAPS_pubpropertyParityReplace

获取或设置一个字节,该字节在发生奇偶校验错误时替换数据流中的无效字节。

System_CAPS_pubpropertyPortName

获取或设置通信端口,包括但不限于所有可用的 COM 端口。

System_CAPS_pubpropertyReadBufferSize

获取或设置 SerialPort 输入缓冲区的大小。

System_CAPS_pubpropertyReadTimeout

获取或设置读取操作未完成时发生超时之前的毫秒数。

System_CAPS_pubpropertyReceivedBytesThreshold

获取或设置 DataReceived 事件发生前内部输入缓冲区中的字节数。

System_CAPS_pubpropertyRtsEnable

获取或设置一个值,该值指示在串行通信中是否启用请求发送 (RTS) 信号。

System_CAPS_pubpropertySite

获取或设置 ISite  Component。(继承自 Component。)

System_CAPS_pubpropertyStopBits

获取或设置每个字节的标准停止位数。

System_CAPS_pubpropertyWriteBufferSize

获取或设置串行端口输出缓冲区的大小。

System_CAPS_pubpropertyWriteTimeout

获取或设置写入操作未完成时发生超时之前的毫秒数。

简单初始化串口参数的示例程序:

复制代码
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);

</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Open the port for communications</span>

port.Open();

</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Write a string</span>
port.Write(<span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">Hello World</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);

</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Write a set of bytes</span>
port.Write(<span style="color: rgb(0, 0, 255);">new</span> <span style="color: rgb(0, 0, 255);">byte</span>[] { <span style="color: rgb(128, 0, 128);">0x0A</span>, <span style="color: rgb(128, 0, 128);">0xE2</span>, <span style="color: rgb(128, 0, 128);">0xFF</span> }, <span style="color: rgb(128, 0, 128);">0</span>, <span style="color: rgb(128, 0, 128);">3</span><span style="color: rgb(0, 0, 0);">);

</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Close the port</span>

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]
    </span><span style="color: rgb(0, 0, 255);">static</span> <span style="color: rgb(0, 0, 255);">void</span> Main(<span style="color: rgb(0, 0, 255);">string</span><span style="color: rgb(0, 0, 0);">[] args)
    {
        </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Instatiate this class</span>
        <span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> SerialPortProgram();
    }

    </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> SerialPortProgram()
    {
        Console.WriteLine(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">Incoming Data:</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);

        </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Attach a method to be called when there
        </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> is data waiting in the port's buffer</span>
        port.DataReceived += <span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">
          SerialDataReceivedEventHandler(port_DataReceived);

        </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Begin communications</span>

port.Open();

        </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Enter an application loop to keep this thread alive</span>

Application.Run();
}

    </span><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">void</span> port_DataReceived(<span style="color: rgb(0, 0, 255);">object</span><span style="color: rgb(0, 0, 0);"> sender, SerialDataReceivedEventArgs e)
    {
        </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Show all the incoming data in the port's buffer</span>

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</span>&lt;<span style="color: rgb(0, 0, 255);">byte</span>&gt; bBuffer = <span style="color: rgb(0, 0, 255);">new</span> List&lt;<span style="color: rgb(0, 0, 255);">byte</span>&gt;<span style="color: rgb(0, 0, 0);">();
    </span><span style="color: rgb(0, 0, 255);">string</span> sBuffer =<span style="color: rgb(0, 0, 0);"> String.Empty;

    </span><span style="color: rgb(0, 0, 255);">static</span> <span style="color: rgb(0, 0, 255);">void</span> Main(<span style="color: rgb(0, 0, 255);">string</span><span style="color: rgb(0, 0, 0);">[] args)
    { </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Program(); }

    Program()
    {
        com.DataReceived </span>+= <span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> SerialDataReceivedEventHandler(com_DataReceived);

        com.Open();

        Console.WriteLine(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">Waiting for incoming data...</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);

        Console.ReadKey();
    }

    </span><span style="color: rgb(0, 0, 255);">void</span> com_DataReceived(<span style="color: rgb(0, 0, 255);">object</span><span style="color: rgb(0, 0, 0);"> sender, SerialDataReceivedEventArgs e)
    {
        </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Use either the binary OR the string technique (but not both)
        </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Buffer and process binary data</span>
        <span style="color: rgb(0, 0, 255);">while</span> (com.BytesToRead &gt; <span style="color: rgb(128, 0, 128);">0</span><span style="color: rgb(0, 0, 0);">)
            bBuffer.Add((</span><span style="color: rgb(0, 0, 255);">byte</span><span style="color: rgb(0, 0, 0);">)com.ReadByte());
        ProcessBuffer(bBuffer);

        </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Buffer string data</span>
        sBuffer +=<span style="color: rgb(0, 0, 0);"> com.ReadExisting();
        ProcessBuffer(sBuffer);
    }

    </span><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">void</span> ProcessBuffer(<span style="color: rgb(0, 0, 255);">string</span><span style="color: rgb(0, 0, 0);"> sBuffer)
    {
        </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Look in the string for useful information
        </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> then remove the useful data from the buffer</span>

}

    </span><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">void</span> ProcessBuffer(List&lt;<span style="color: rgb(0, 0, 255);">byte</span>&gt;<span style="color: rgb(0, 0, 0);"> bBuffer)
    {
        </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Look in the byte array for useful information
        </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> then remove the useful data from the buffer</span>

}
}
}

复制代码

  • 1
    点赞
  • 0
    评论
  • 1
    收藏
  • 扫一扫,分享海报

参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:技术黑板 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值