|
发表于 2013-10-9 16:28:09
|
显示全部楼层
Shaw.Embedi 发表于 2013-10-8 10:10
时过一年多,楼主的问题解决了没有
我最近也是在用serialport,同样发现该问题
而且占用的CPU比你还高。
我前一段时间用api实现了串口,代码如下
//===========================================================================//
// 串口API操作部分
//===========================================================================//
//win32 api constants
private const uint GENERIC_READ = 0x80000000;
private const uint GENERIC_WRITE = 0x40000000;
private const int OPEN_EXISTING = 3;
private const int INVALID_HANDLE_VALUE = -1;
//
// PURGE function flags.
//
private const int PURGE_TXABORT = 0x01; // Kill the pending/current writes to the comm port.
private const int PURGE_RXABORT = 0x02; // Kill the pending/current reads to the comm port.
private const int PURGE_TXCLEAR = 0x04; // Kill the transmit queue if there.
private const int PURGE_RXCLEAR = 0x08; // Kill the typeahead buffer if there.
private const int ERROR_IO_PENDING = 997;
private const uint INFINITE = 0xFFFFFFFF;
[StructLayout(LayoutKind.Sequential)]
private struct DCB
{
//taken from c struct in platform sdk
public int DCBlength; // sizeof(DCB)
public int BaudRate; // current baud rate
public int fBinary; // binary mode, no EOF check
public int fParity; // enable parity checking
public int fOutxCtsFlow; // CTS output flow control
public int fOutxDsrFlow; // DSR output flow control
public int fDtrControl; // DTR flow control type
public int fDsrSensitivity; // DSR sensitivity
public int fTXContinueOnXoff; // XOFF continues Tx
public int fOutX; // XON/XOFF out flow control
public int fInX; // XON/XOFF in flow control
public int fErrorChar; // enable error replacement
public int fNull; // enable null stripping
public int fRtsControl; // RTS flow control
public int fAbortOnError; // abort on error
public int fDummy2; // reserved
public ushort wReserved; // not currently used
public ushort XonLim; // transmit XON threshold
public ushort XoffLim; // transmit XOFF threshold
public byte ByteSize; // number of bits/byte, 4-8
public byte Parity; // 0-4=no,odd,even,mark,space
public byte StopBits; // 0,1,2 = 1, 1.5, 2
public char XonChar; // Tx and Rx XON character
public char XoffChar; // Tx and Rx XOFF character
public char ErrorChar; // error replacement character
public char EofChar; // end of input character
public char EvtChar; // received event character
public ushort wReserved1; // reserved; do not use
}
[StructLayout(LayoutKind.Sequential)]
private struct COMMTIMEOUTS
{
public int ReadIntervalTimeout;
public int ReadTotalTimeoutMultiplier;
public int ReadTotalTimeoutConstant;
public int WriteTotalTimeoutMultiplier;
public int WriteTotalTimeoutConstant;
}
[StructLayout(LayoutKind.Sequential)]
private struct OVERLAPPED
{
public int Internal;
public int InternalHigh;
public int Offset;
public int OffsetHigh;
public int hEvent;
}
[DllImport("kernel32.dll")]
private static extern int CreateFile(
string lpFileName, // file name
uint dwDesiredAccess, // access mode
int dwShareMode, // share mode
int lpSecurityAttributes, // SD
int dwCreationDisposition, // how to create
int dwFlagsAndAttributes, // file attributes
int hTemplateFile // handle to template file
);
[DllImport("kernel32.dll")]
private static extern bool CloseHandle(
int hObject // handle to object
);
[DllImport("kernel32.dll")]
private static extern bool ReadFile(
int hFile, // handle to file
byte[] lpBuffer, // data buffer
int nNumberOfBytesToRead, // number of bytes to read
ref int lpNumberOfBytesRead, // number of bytes read
ref OVERLAPPED lpOverlapped // overlapped buffer
);
[DllImport("kernel32.dll")]
private static extern bool WriteFile(
int hFile, // handle to file
byte[] lpBuffer, // data buffer
int nNumberOfBytesToWrite, // number of bytes to write
ref int lpNumberOfBytesWritten, // number of bytes written
ref OVERLAPPED lpOverlapped // overlapped buffer
);
[DllImport("kernel32.dll")]
private static extern bool SetCommTimeouts(
int hFile, // handle to comm device
ref COMMTIMEOUTS lpCommTimeouts // time-out values
);
[DllImport("kernel32.dll")]
private static extern bool GetCommTimeouts(
int hFile, // handle to comm device
ref COMMTIMEOUTS lpCommTimeouts // time-out values
);
[DllImport("kernel32.dll")]
private static extern bool SetCommState(
int hFile, // handle to communications device
ref DCB lpDCB // device-control block
);
[DllImport("kernel32.dll")]
private static extern bool GetCommState(
int hFile, // handle to communications device
ref DCB lpDCB // device-control block
);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool PurgeComm(int hFile, uint dwFlags);
[DllImport("kernel32")]
private static extern bool SetupComm(int hFile, int dwInQueue, int dwOutQueue);
[DllImport("kernel32.dll")]
public static extern uint GetLastError();
/*
[DllImport("kernel32.dll")]
private static extern bool BuildCommDCB(
string lpDef, // device-control string
ref DCB lpDCB // device-control block
);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EventModify(int hEvent, [In, MarshalAs(UnmanagedType.U4)] int dEvent);
[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto)]
public static extern int CreateEventA(int lpEventAttributes, [In, MarshalAs(UnmanagedType.Bool)] bool bManualReset, [In, MarshalAs(UnmanagedType.Bool)] bool bIntialState, [In, MarshalAs(UnmanagedType.BStr)] string lpName);
[DllImport("kernel32.dll")]
public static extern bool ResetEvent(int hEvent);
[DllImport("kernel32.dll")]
public static extern bool ClearCommError(int hFile, ref uint lpErrors, ref COMSTAT lpStat);
[DllImport("kernel32.dll")]
private static extern int WaitForSingleObject(int hHandle, uint dwMilliseconds);
[DllImport("kernel32.dll")]
private static extern bool GetOverlappedResult(int hFile, ref OVERLAPPED lpOverlapped, ref uint lpNumberOfBytesTransferred, bool bWait);
public struct COMSTAT
{
public uint fCtsHold;
public uint fDsrHold;
public uint fRlsdHold;
public uint fXoffHold;
public uint fXoffSent;
public uint fEof;
public uint fTxim;
public uint fReserved;
public uint cbInQue;
public uint cbOutQue;
};
public enum EventFlags
{
PULSE = 1,
RESET = 2,
SET = 3
}
*/
//private OVERLAPPED m_oSend = new OVERLAPPED();
//private OVERLAPPED m_oRecv = new OVERLAPPED();
/******************************************************************************
* 函数名:MySerialOpen, MySerialClose
* 输 入:
* 输 出:
* 功 能:利用Windows API函数打开与关闭串口
******************************************************************************/
private int hCom;
private int ReadTimeout = 2000; //读超时
private long m_dwSysErrCode = 0;
private bool m_IsOpened = false;
private bool MySerialOpen()
{
hCom = INVALID_HANDLE_VALUE;
DCB dcbCommPort = new DCB();
COMMTIMEOUTS ctoCommPort = new COMMTIMEOUTS();
// OPEN THE COMM PORT.
hCom = CreateFile(barEditItemUsart.EditValue.ToString(),
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
0,
0);
// IF THE PORT CANNOT BE OPENED, BAIL OUT.
if (hCom == INVALID_HANDLE_VALUE)
{
MessageBox.Show("Com port can not be opened!");
CloseHandle(hCom);
return false;
}
PurgeComm(hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
if (SetupComm(hCom, m_MaxPackageSize, m_MaxPackageSize) == false)
{
m_dwSysErrCode = GetLastError();
CloseHandle(hCom);
return false;
}
dcbCommPort.DCBlength = Marshal.SizeOf(dcbCommPort);
if (GetCommState(hCom, ref dcbCommPort) == false)
{
m_dwSysErrCode = GetLastError();
CloseHandle(hCom);
return false;
}
else
{
// SET BAUD RATE, PARITY, WORD SIZE, AND STOP BITS.
// THERE ARE OTHER WAYS OF DOING SETTING THESE BUT THIS IS THE EASIEST.
// IF YOU WANT TO LATER ADD CODE FOR OTHER BAUD RATES, REMEMBER
// THAT THE ARGUMENT FOR BuildCommDCB MUST BE A POINTER TO A STRING.
// ALSO NOTE THAT BuildCommDCB() DEFAULTS TO NO HANDSHAKING.
dcbCommPort.BaudRate = Convert.ToInt32(barEditItemBaud.EditValue.ToString());
dcbCommPort.Parity = 0;//"0NONE 1Odd 2Even 3Mark 4Space"
dcbCommPort.ByteSize = 8;
dcbCommPort.StopBits = 1;//"0NONE 1One 2Two 3OnePointFive
SetCommState(hCom, ref dcbCommPort);
}
GetCommTimeouts(hCom, ref ctoCommPort);
ctoCommPort.ReadIntervalTimeout = 10;
ctoCommPort.ReadTotalTimeoutMultiplier = 1;
ctoCommPort.ReadTotalTimeoutConstant = 1;
ctoCommPort.WriteTotalTimeoutMultiplier = 1000;
ctoCommPort.WriteTotalTimeoutConstant = 500000;
SetCommTimeouts(hCom, ref ctoCommPort);
//m_oSend.hEvent = CreateEventA(null, false, false, null);
//m_oRecv.hEvent = CreateEventA(null, false, false, null);
m_IsOpened = true;
return true;
}
private bool MySerialClose()
{
if (hCom != INVALID_HANDLE_VALUE)
{
CloseHandle(hCom);
Thread.Sleep(60);
hCom = INVALID_HANDLE_VALUE;
}
m_IsOpened = false;
return true;
}
private void ComReceiveThreadFunc()
{
byte[] buf = new byte[1024];
int nr = 0;
uint dwRead = 0;
bool bResult = false;
while (m_RecvThreadStopFlag != true)
{
byte[] BufBytes = new byte[1024];
if (hCom != INVALID_HANDLE_VALUE)
{
OVERLAPPED ovlCommPort = new OVERLAPPED();
int BytesRead = 0;
ReadFile(hCom, BufBytes, 1024, ref BytesRead, ref ovlCommPort);
if (BytesRead != 0)
{
lock (myLock)
{
for (int i = 0; i < BytesRead; i++)
{
receiveBuffQueue.Enqueue(BufBytes);
receiveBuffSemaphore.Release(1);
receiveBuffShowQueue.Enqueue(BufBytes);
m_totalByte++;
}
}
}
}
}
}
public int ComWriteBuf(byte[] byteBuf, int dwLen)
{
if (byteBuf.Length == 0)
return 0;
if (hCom != INVALID_HANDLE_VALUE)
{
OVERLAPPED ovlCommPort = new OVERLAPPED();
int bytesWritten = 0;
WriteFile(hCom, byteBuf, dwLen, ref bytesWritten, ref ovlCommPort);
return bytesWritten;
}
else
{
return -1;
}
}
具体的效率我也没有来得及测试,仅供参考。 |
|