通常,在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));
}