天天看點

C#利用API函數開發序列槽通訊(四)

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

}

繼續閱讀