?? port.cs
字號:
dcb.fErrorChar = portSettings.ReplaceErrorChar;
dcb.fInX = portSettings.InX;
dcb.fNull = portSettings.DiscardNulls;
dcb.fOutX = portSettings.OutX;
dcb.fOutxCtsFlow = portSettings.OutCTS;
dcb.fOutxDsrFlow = portSettings.OutDSR;
dcb.fParity = (portSettings.BasicSettings.Parity == Parity.none) ? false : true;
dcb.fRtsControl = (DCB.RtsControlFlags)portSettings.RTSControl;
dcb.fTXContinueOnXoff = portSettings.TxContinueOnXOff;
dcb.Parity = (byte)portSettings.BasicSettings.Parity;
dcb.StopBits = (byte)portSettings.BasicSettings.StopBits;
dcb.XoffChar = (sbyte)portSettings.XoffChar;
dcb.XonChar = (sbyte)portSettings.XonChar;
dcb.XonLim = dcb.XoffLim = (ushort)(rxBufferSize / 10);
m_CommAPI.SetCommState(hPort, dcb);
// store some state values
brk = 0;
dtr = dcb.fDtrControl == DCB.DtrControlFlags.Enable ? 1 : 0;
rts = dcb.fRtsControl == DCB.RtsControlFlags.Enable ? 1 : 0;
// set the Comm timeouts
CommTimeouts ct = new CommTimeouts();
// reading we'll return immediately
// this doesn't seem to work as documented
ct.ReadIntervalTimeout = uint.MaxValue; // this = 0xffffffff
ct.ReadTotalTimeoutConstant = 0;
ct.ReadTotalTimeoutMultiplier = 0;
// writing we'll give 5 seconds
ct.WriteTotalTimeoutConstant = 5000;
ct.WriteTotalTimeoutMultiplier = 0;
m_CommAPI.SetCommTimeouts(hPort, ct);
// read the ports capabilities
bool status=GetPortProperties();
// start the receive thread
eventThread = new Thread(new ThreadStart(CommEventThread));
eventThread.Priority = ThreadPriority.Highest;
eventThread.Start();
// wait for the thread to actually get spun up
threadStarted.WaitOne();
return true;
}
/// <summary>
/// Query the current port's capabilities without accessing it. You can only call the Close()
/// method after reading the capabilities. This method does neither initialize nor Open() the
/// port.
/// </summary>
///
/// <example>
///
/// </example>
public bool Query()
{
if(isOpen) return false;
hPort = m_CommAPI.QueryFile(portName);
if(hPort == (IntPtr)CommAPI.INVALID_HANDLE_VALUE)
{
int e = Marshal.GetLastWin32Error();
if(e == (int)APIErrors.ERROR_ACCESS_DENIED)
{
// port is unavailable
return false;
}
// ClearCommError failed!
string error = String.Format("CreateFile Failed: {0}", e);
throw new CommPortException(error);
}
// read the port's capabilities
bool status=GetPortProperties();
return true;
}
// parameters without closing and reopening the port
/// <summary>
/// Updates communication settings of the port
/// </summary>
/// <returns>true if successful, false if it fails</returns>
private bool UpdateSettings()
{
if(!isOpen) return false;
// transfer the port settings to a DCB structure
dcb.BaudRate = (uint)portSettings.BasicSettings.BaudRate;
dcb.ByteSize = portSettings.BasicSettings.ByteSize;
dcb.EofChar = (sbyte)portSettings.EOFChar;
dcb.ErrorChar = (sbyte)portSettings.ErrorChar;
dcb.EvtChar = (sbyte)portSettings.EVTChar;
dcb.fAbortOnError = portSettings.AbortOnError;
dcb.fBinary = true;
dcb.fDsrSensitivity = portSettings.DSRSensitive;
dcb.fDtrControl = (DCB.DtrControlFlags)portSettings.DTRControl;
dcb.fErrorChar = portSettings.ReplaceErrorChar;
dcb.fInX = portSettings.InX;
dcb.fNull = portSettings.DiscardNulls;
dcb.fOutX = portSettings.OutX;
dcb.fOutxCtsFlow = portSettings.OutCTS;
dcb.fOutxDsrFlow = portSettings.OutDSR;
dcb.fParity = (portSettings.BasicSettings.Parity == Parity.none) ? false : true;
dcb.fRtsControl = (DCB.RtsControlFlags)portSettings.RTSControl;
dcb.fTXContinueOnXoff = portSettings.TxContinueOnXOff;
dcb.Parity = (byte)portSettings.BasicSettings.Parity;
dcb.StopBits = (byte)portSettings.BasicSettings.StopBits;
dcb.XoffChar = (sbyte)portSettings.XoffChar;
dcb.XonChar = (sbyte)portSettings.XonChar;
dcb.XonLim = dcb.XoffLim = (ushort)(rxBufferSize / 10);
return m_CommAPI.SetCommState(hPort, dcb);
}
/// <summary>
/// Close the current serial port
/// </summary>
/// <returns>true indicates success, false indicated failure</returns>
public bool Close()
{
if(txOverlapped != IntPtr.Zero)
{
LocalFree(txOverlapped);
txOverlapped = IntPtr.Zero;
}
if(!isOpen) return false;
isOpen = false; // to help catch intentional close
if(m_CommAPI.CloseHandle(hPort))
{
m_CommAPI.SetEvent(closeEvent);
isOpen = false;
hPort = (IntPtr)CommAPI.INVALID_HANDLE_VALUE;
m_CommAPI.SetEvent(closeEvent);
return true;
}
return false;
}
/// <summary>
/// The Port's output buffer. Set this property to send data.
/// </summary>
public byte[] Output
{
set
{
if(!isOpen)
throw new CommPortException("Port not open");
int written = 0;
// more than threshold amount so send without buffering
if(value.GetLength(0) > sthreshold)
{
// first send anything already in the buffer
if(ptxBuffer > 0)
{
m_CommAPI.WriteFile(hPort, txBuffer, ptxBuffer, ref written, txOverlapped);
ptxBuffer = 0;
}
m_CommAPI.WriteFile(hPort, value, (int)value.GetLength(0), ref written, txOverlapped);
}
else
{
// copy it to the tx buffer
value.CopyTo(txBuffer, (int)ptxBuffer);
ptxBuffer += (int)value.Length;
// now if the buffer is above sthreshold, send it
if(ptxBuffer >= sthreshold)
{
m_CommAPI.WriteFile(hPort, txBuffer, ptxBuffer, ref written, txOverlapped);
ptxBuffer = 0;
}
}
}
}
/// <summary>
/// The Port's input buffer. Incoming data is read from here and a read will pull InputLen bytes from the buffer
/// <seealso cref="InputLen"/>
/// </summary>
public byte[] Input
{
get
{
if(!isOpen) return null;
int dequeueLength = 0;
// lock the rx FIFO while reading
rxBufferBusy.WaitOne();
// how much data are we *actually* going to return from the call?
if(inputLength == 0)
dequeueLength = rxFIFO.Count; // pull the entire buffer
else
dequeueLength = (inputLength < rxFIFO.Count) ? inputLength : rxFIFO.Count;
byte[] data = new byte[dequeueLength];
// dequeue the data
for(int p = 0 ; p < dequeueLength ; p++)
data[p] = (byte)rxFIFO.Dequeue();
// release the mutex so the Rx thread can continue
rxBufferBusy.ReleaseMutex();
return data;
}
}
/// <summary>
/// The length of the input buffer
/// </summary>
public int InputLen
{
get
{
return inputLength;
}
set
{
inputLength = value;
}
}
/// <summary>
/// The actual amount of data in the input buffer
/// </summary>
public int InBufferCount
{
get
{
if(!isOpen) return 0;
return rxFIFO.Count;
}
}
/// <summary>
/// The actual amount of data in the output buffer
/// </summary>
public int OutBufferCount
{
get
{
if(!isOpen) return 0;
return ptxBuffer;
}
}
/// <summary>
/// The number of bytes that the receive buffer must exceed to trigger a Receive event
/// </summary>
public int RThreshold
{
get
{
return rthreshold;
}
set
{
rthreshold = value;
}
}
/// <summary>
/// The number of bytes that the transmit buffer must exceed to trigger a Transmit event
/// </summary>
public int SThreshold
{
get
{
return sthreshold;
}
set
{
sthreshold = value;
}
}
/// <summary>
/// Send or check for a communications BREAK event
/// </summary>
public bool Break
{
get
{
if(!isOpen) return false;
return (brk == 1);
}
set
{
if(!isOpen) return;
if(brk < 0) return;
if(hPort == (IntPtr)CommAPI.INVALID_HANDLE_VALUE) return;
if (value)
{
if (m_CommAPI.EscapeCommFunction(hPort, CommEscapes.SETBREAK))
brk = 1;
else
throw new CommPortException("Failed to set break!");
}
else
{
if (m_CommAPI.EscapeCommFunction(hPort, CommEscapes.CLRBREAK))
brk = 0;
else
throw new CommPortException("Failed to clear break!");
}
}
}
/// <summary>
/// Returns whether or not the current port support a DTR signal
/// </summary>
public bool DTRAvailable
{
get
{
return dtravail;
}
}
/// <summary>
/// Gets or sets the current DTR line state (true = 1, false = 0)
/// </summary>
public bool DTREnable
{
get
{
return (dtr == 1);
}
set
{
if(dtr < 0) return;
if(hPort == (IntPtr)CommAPI.INVALID_HANDLE_VALUE) return;
if (value)
{
if (m_CommAPI.EscapeCommFunction(hPort, CommEscapes.SETDTR))
dtr = 1;
else
throw new CommPortException("Failed to set DTR!");
}
else
{
if (m_CommAPI.EscapeCommFunction(hPort, CommEscapes.CLRDTR))
dtr = 0;
else
throw new CommPortException("Failed to clear DTR!");
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -