通常,在C#中实现串口通信,常用方法有两种:
第一:通过MSCOMM控件这是最简单的,最方便的方法。可功能上很难做到控制自如,同时这个控件并不是系统本身所带,所以还得注册。
第二:自己用API写串口通信,这样难度高点,但对于我们来说,可以方便实现自己想要的各种功能。
今天我们采用第二种方法实现串口通讯。
第五:定义串口通讯使用函数
//初始化串口配置信息
public void InitCom(string comPort, int baudRate, byte byteSize, byte parity, byte stopBits)
{
this.ComPort =comPort;
this.BaudRate = baudRate;
this.ByteSize = byteSize;
this.Parity = parity;
this.StopBits = stopBits;
}
//打开串口
public bool OpenCom()
{
//判断串口是否已经打开
if (comHandle != IntPtr.Zero)
{
//throw new IOException("Streamalreadyopened.");
return true;
}
//打开串口
comHandle = CreateFile("\\\\.\\"+ComPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, File_Flag_WRITE_THROUGH, 0);
//判断是否打开成功
if (comHandle.ToString() == "-1")
{
comHandle = IntPtr.Zero;
return false;
}
if (comHandle == IntPtr.Zero)
{
comHandle = IntPtr.Zero;
return false;
}
//设置缓冲区大小
if (!SetupComm(comHandle, 10000, 10000))
{
CloseHandle(comHandle);
comHandle = IntPtr.Zero;
ComPort = null;
return false;
}
//设置DCB
if (!SetPortSettings(this.BaudRate, this.Parity, this.ByteSize, this.StopBits))
{
CloseHandle(comHandle);
comHandle = IntPtr.Zero;
ComPort = null;
return false;
}
//设置超时时间
if (!SetTimeouts(100, 500, 50, 500, 50))
{
CloseHandle(comHandle);
comHandle = IntPtr.Zero;
ComPort = null;
return false;
}
//清除串口缓冲区中的读写信息
if (!PurgeComm())
{
CloseHandle(comHandle);
comHandle = IntPtr.Zero;
ComPort = null;
return false;
}
return true;
}
//关闭串口
public bool CloseCom()
{
//判断串口是否已经发关闭
if (comHandle == IntPtr.Zero)
{
return true;
}
//关闭串口
if (!CloseHandle(comHandle))
{
return false;
}
comHandle = IntPtr.Zero;
ComPort = null;
return true;
}
//设置效验位
public bool SetComMark(byte mark)
{
if (!SetPortSettings(this.BaudRate, mark, this.ByteSize, this.StopBits))
{
return false;
}
return true;
}
//设置串口DCB
public bool SetPortSettings(int baudrate, byte parity, byte databits, byte stopbits)
{
string def;
string par;//效验位
par = "N";
switch(parity)
{
case 0:
par = "N";
break;
case 1:
par = "O";
break;
case 2:
par = "E";
break;
case 3:
par = "M";
break;
case 4:
par = "S";
break;
}
def = ComPort + ":" + baudrate.ToString() + "," + par + "," + databits.ToString() + "," + stopbits.ToString();
dcbCommPort.DCBlength = Marshal.SizeOf(dcbCommPort);
if (!GetCommState(comHandle, ref dcbCommPort))
{
return false;
}
if (!BuildCommDCB(def, ref dcbCommPort))
{
return false;
}
return SetCommState(comHandle, ref dcbCommPort);
}
//设置串口超时时间
public bool SetTimeouts(int ReadIntervalTimeout, int ReadTotalTimeoutMultiplier, int ReadTotalTimeoutConstant,
int WriteTotalTimeoutMultiplier, int WriteTotalTimeoutConstant)
{
if (!GetCommTimeouts(comHandle, out ctoCommPort))
{
return false;
}
ctoCommPort.ReadIntervalTimeout = ReadIntervalTimeout;
ctoCommPort.ReadTotalTimeoutConstant = ReadTotalTimeoutConstant;
ctoCommPort.ReadTotalTimeoutMultiplier = ReadTotalTimeoutMultiplier;
ctoCommPort.WriteTotalTimeoutConstant = WriteTotalTimeoutConstant;
ctoCommPort.WriteTotalTimeoutMultiplier = WriteTotalTimeoutMultiplier;
return SetCommTimeouts(comHandle, ref ctoCommPort);
}
//清空缓冲区
public bool PurgeComm()
{
return PurgeComm(comHandle,(PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR));
}