SerialPort类的⽤法与⽰例
Microsoft .Net框架SerialPort类的⽤法与⽰例
从Microsoft .Net 2.0版本以后,就默认提供了System.IO.Ports.SerialPort类,⽤户可以⾮常简单地编写少量代码就完成串⼝的信息收发程序。本⽂将介绍如何在PC端⽤C# .Net 来开发串⼝应⽤程序。
1. 串⼝硬件信号定义
DB9 Connector 信号定义
针脚信号定义作⽤
1DCD载波检测Received Line Signal Detector(Data Carrier Detect)
2RXD接收数据Received Data
3TXD发送数据Transmit Data
4DTR数据终端准备好Data Terminal Ready
乡村爱情拍摄基地5SGND信号地Signal Ground
6DSR数据准备好Data Set Ready
7RTS请求发送Request To Send
8CTS清除发送Clear To Send
9RI振铃提⽰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_BaBoard, // 主板
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_GroupUr, // 系统组帐号
Win32_UrAccount, // ⽤户帐号
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 archer = new ManagementObjectSearcher("lect * from " + hardType))
{
var hardInfos = archer.Get();
foreach (var hardInfo in hardInfos)
{
if (hardInfo.Properties[propKey].Value.ToString().Contains("COM"))
{
strs.Add(hardInfo.Properties[propKey].Value.ToString());
}
}
archer.Dispo();
}
return strs.ToArray();
}
catch
{
return null;
}
finally
{ strs = null; }
}
//通过WMI获取COM端⼝
string[] portList = MulGetHardwareInfo(HardwareEnum.Win32_PnPEntity, "Name");
3. 串⼝属性参数设置
参见MSDN上的帮助⽂件,SerialPort类所包含的属性详见下表。
名称说明
BaStream获取 Stream 对象的基础 SerialPort 对象。
BaudRate获取或设置串⾏波特率。
BreakState获取或设置中断信号状态。
BytesToRead获取接收缓冲区中数据的字节数。
BytesToWrite获取发送缓冲区中数据的字节数。
CanRaiEvents获取⼀个值,该值指⽰组件是否可以引发⼀个事件。(继承⾃ Component。)
CDHolding获取端⼝的载波检测⾏的状态。
Container获取 IContainer ,其中包含 Component。(继承⾃ Component。)跑步的
获取“可以发送”⾏的状态。
CtsHolding 获取“可以发送”⾏的状态。
DataBits获取或设置每个字节的标准数据位长度。
DesignMode获取⼀个值,该值指⽰是否 Component 当前处于设计模式。(继承
⾃ Component。)
DiscardNull获取或设置⼀个值,该值指⽰ null 字节在端⼝和接收缓冲区之间传输时是否被忽
略。
DsrHolding获取数据设置就绪 (DSR) 信号的状态。
DtrEnable获取或设置⼀个值,该值在串⾏通信过程中启⽤数据终端就绪 (DTR) 信号。
Encoding获取或设置传输前后⽂本转换的字节编码。
Events获取的事件处理程序附加到此列表 Component。(继承⾃ Component。)
Handshake使⽤ Handshake 中的值获取或设置串⾏端⼝数据传输的握⼿协议。
IsOpen获取⼀个值,该值指⽰ SerialPort 对象的打开或关闭状态。
NewLine获取或设置⽤于解释 ReadLine 和 WriteLine ⽅法调⽤结束的值。
Parity获取或设置奇偶校验检查协议。
ParityReplace获取或设置⼀个字节,该字节在发⽣奇偶校验错误时替换数据流中的⽆效字节。
PortName获取或设置通信端⼝,包括但不限于所有可⽤的 COM 端⼝。
ReadBufferSize获取或设置 SerialPort 输⼊缓冲区的⼤⼩。
ReadTimeout获取或设置读取操作未完成时发⽣超时之前的毫秒数。
ReceivedBytesThreshold获取或设置 DataReceived 事件发⽣前内部输⼊缓冲区中的字节数。
RtsEnable获取或设置⼀个值,该值指⽰在串⾏通信中是否启⽤请求发送 (RTS) 信号。
Site获取或设置 ISite 的 Component。(继承⾃ Component。)
StopBits获取或设置每个字节的标准停⽌位数。
WriteBufferSize获取或设置串⾏端⼝输出缓冲区的⼤⼩。
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 ttings
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 t of bytes
port.Write(new byte[] { 0x0A, 0xE2, 0xFF }, 0, 3);
// Clo the port
圆柱的公式port.Clo();
}
下⾯是如何发送⼀个⽂本⽂件的例⼦:
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 rial port with basic ttings
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 nder, 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 ");
Console.ReadKey();
}
void com_DataReceived(object nder, SerialDataReceivedEventArgs e)
{
// U 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 uful information
// then remove the uful data from the buffer
}
private void ProcessBuffer(List<byte> bBuffer)
{
// Look in the byte array for uful information
// then remove the uful data from the buffer
}
}
}