在Wince和Windows Mobile下,很多设备以串口(Serial Port/Com Port)的方式提供访问接口,例如可以通过串口访问GPS的receiver,从而接收NMEA Data。
在CF.NET2.0开始,MS把串口操作封装了到System.IO.Ports.SerialPort里面,大大简便了对串口的操作,不再需要P/Invoke就可以直接操作串口。
下面展现两个串口通信类,一个负责发生,一个负责接收,两个类分别在不要的设备上运行。
public class ReceiverPort : IDisposable
{
private readonly System.IO.Ports.SerialPort serialPort;
public ReceiverPort()
{
serialPort = new System.IO.Ports.SerialPort("COM1", 4800,
System.IO.Ports.Parity.None, 8,
System.IO.Ports.StopBits.One);
serialPort.Handshake = System.IO.Ports.Handshake.None;
try
{
serialPort.DataReceived += new
System.IO.Ports.SerialDataReceivedEventHandler(this.serialPort_DataReceived);
serialPort.Open();
if (serialPort.IsOpen)
{
Console.WriteLine("Open the serial port successful");
}
else
{
Console.WriteLine("Fail to open the serial port");
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
public void Dispose()
{
if (serialPort.IsOpen)
{
serialPort.Close();
}
serialPort.Dispose();
}
private void serialPort_DataReceived(object sender,
System.IO.Ports.SerialDataReceivedEventArgs e)
{
Console.WriteLine("RECEIVED:" + serialPort.ReadLine());
}
}
public class SenderPort : IDisposable
{
private readonly System.IO.Ports.SerialPort serialPort;
public SenderPort()
{
serialPort = new System.IO.Ports.SerialPort("COM1", 4800,
System.IO.Ports.Parity.None, 8,
System.IO.Ports.StopBits.One);
serialPort.Handshake = System.IO.Ports.Handshake.None;
try
{
serialPort.Open();
if (serialPort.IsOpen)
{
Console.WriteLine("Open the serial port successful");
}
else
{
Console.WriteLine("Fail to open the serial port");
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
public void Dispose()
{
if (serialPort.IsOpen)
{
serialPort.Close();
}
serialPort.Dispose();
}
public bool Send(string str)
{
try
{
if (serialPort.IsOpen)
{
Console.WriteLine("SENT:" + str);
serialPort.WriteLine(str + "\r");
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return false;
}
}
}
{
private readonly System.IO.Ports.SerialPort serialPort;
public ReceiverPort()
{
serialPort = new System.IO.Ports.SerialPort("COM1", 4800,
System.IO.Ports.Parity.None, 8,
System.IO.Ports.StopBits.One);
serialPort.Handshake = System.IO.Ports.Handshake.None;
try
{
serialPort.DataReceived += new
System.IO.Ports.SerialDataReceivedEventHandler(this.serialPort_DataReceived);
serialPort.Open();
if (serialPort.IsOpen)
{
Console.WriteLine("Open the serial port successful");
}
else
{
Console.WriteLine("Fail to open the serial port");
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
public void Dispose()
{
if (serialPort.IsOpen)
{
serialPort.Close();
}
serialPort.Dispose();
}
private void serialPort_DataReceived(object sender,
System.IO.Ports.SerialDataReceivedEventArgs e)
{
Console.WriteLine("RECEIVED:" + serialPort.ReadLine());
}
}
public class SenderPort : IDisposable
{
private readonly System.IO.Ports.SerialPort serialPort;
public SenderPort()
{
serialPort = new System.IO.Ports.SerialPort("COM1", 4800,
System.IO.Ports.Parity.None, 8,
System.IO.Ports.StopBits.One);
serialPort.Handshake = System.IO.Ports.Handshake.None;
try
{
serialPort.Open();
if (serialPort.IsOpen)
{
Console.WriteLine("Open the serial port successful");
}
else
{
Console.WriteLine("Fail to open the serial port");
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
public void Dispose()
{
if (serialPort.IsOpen)
{
serialPort.Close();
}
serialPort.Dispose();
}
public bool Send(string str)
{
try
{
if (serialPort.IsOpen)
{
Console.WriteLine("SENT:" + str);
serialPort.WriteLine(str + "\r");
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return false;
}
}
}
进行串口通信,需要通信双方执行共同的协议,所谓共同的协议就是通信的参数相同,通信参数包括BaudRate,Parity,DataBits,StopBits和Handshake。比较关键的是波特率(BaudRate),通信想法BaudRate应该一样。
SerialPort的构造函数第一个参数是端口号,端口号一般由'COM'加上数字组成,例如例子上的COM1。
所有的串口操作都是基于logic serial port(逻辑串口),并不是physical serial port(物理串口),逻辑串口到物理串口是有驱动程序进行映射到,也就是在使用的设备上安装相应的驱动程序,这个逻辑串口就存在,对这个逻辑串口操作并不是说可以正常通信,还需要检查硬件连接。对逻辑串口操作有一个好处是同样的程序可以对物理的串口或者虚拟的串口进行操作。
在ReceiverPort需要注册一个接收函数serialPort_DataReceived到delegate,这样当接收到数据时就回调这个处理函数。