?? cserial.cpp
字號:
#include "CSerial.h"
CSerial::CSerial(void){
m_bOpened = false;
}
CSerial::~CSerial(void){
}
BOOL CSerial::Open(int nPort,int nBaud )
{
if( m_bOpened ) return( TRUE );
char szPort[15];
DCB dcb;
wsprintf( szPort, "COM%d", nPort );
m_hComDev = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL );
//CreateFile用指定的方式打開指定的串口
//m_hCom為文件句柄。
//GENERIC_READ | GENERIC_WRITE指定可以對串口進行讀寫操作。
//參數0表示串口為獨占打開。
//OPEN_EXISTING當指定串口不存在時,返回失敗。
//FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED表示文件屬性。
//打開串口時,須指定 FILE_FLAG_OVERLAPPED,表示文件或設備不會維護訪問指針,
//在讀寫時,須使用OVERLAPPED 結構指定訪問的文件偏移量。
if( m_hComDev == NULL ) return( FALSE );
memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );
//COMMTIMEOUTS:串口超時參數設置
COMMTIMEOUTS CommTimeOuts;
CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
//ReadIntervalTimeout:兩字符之間最大的延時,當讀取串口數據時,
//一旦兩個字符傳輸的時間差超過該時間,讀取函數將返回現有的數據。
//設置為0表示該參數不起作用。
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;//讀取每字符間的超時。
CommTimeOuts.ReadTotalTimeoutConstant = 0;//一次讀取串口數據的固定超時。
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;//寫入每字符間的超時。
CommTimeOuts.WriteTotalTimeoutConstant = 5000;//一次寫入串口數據的固定超時。
SetCommTimeouts( m_hComDev, &CommTimeOuts );
//SetCommTimeouts函數設置某設備句柄的超時參數,要得到某設備句柄的超時參數可以用GetCommTimeouts函數
m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
//DCB:串口參數設置
dcb.DCBlength = sizeof( DCB );
GetCommState( m_hComDev, &dcb );
dcb.BaudRate = nBaud;//串口的通訊速度。如為9600
dcb.ByteSize = 8;//字節位數
if( !SetCommState( m_hComDev, &dcb ) ||
!SetupComm( m_hComDev, 10000, 10000 ) ||//設置串口輸入、輸出緩沖區
m_OverlappedRead.hEvent == NULL ||
m_OverlappedWrite.hEvent == NULL ){
DWORD dwError = GetLastError();
if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
CloseHandle( m_hComDev );
return FALSE;
}
m_bOpened = TRUE;
return m_bOpened;
}
int CSerial::InBufferCount( void )
{
if( !m_bOpened || m_hComDev == NULL ) return( 0 );
DWORD dwErrorFlags;
COMSTAT ComStat;
ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
return (int)ComStat.cbInQue;
}
DWORD CSerial::ReadData( void *buffer, DWORD dwBytesRead)
{
if( !m_bOpened || m_hComDev == NULL ) return 0;
BOOL bReadStatus;
DWORD dwErrorFlags;
COMSTAT ComStat;
ClearCommError( m_hComDev, &dwErrorFlags, &ComStat );
if( !ComStat.cbInQue ) return 0;
dwBytesRead = min(dwBytesRead,(DWORD) ComStat.cbInQue);
//ReadFile:讀取串口數據
bReadStatus = ReadFile( m_hComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );
if( !bReadStatus ){
if( GetLastError() == ERROR_IO_PENDING ){
WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
return dwBytesRead;
}
return 0;
}
return dwBytesRead;
}
DWORD CSerial::SendData( const char *buffer, DWORD dwBytesWritten)
{
if( !m_bOpened || m_hComDev == NULL ) return( 0 );
BOOL bWriteStat;
//WriteFile:向串口寫數據
bWriteStat = WriteFile( m_hComDev, buffer, dwBytesWritten, &dwBytesWritten, &m_OverlappedWrite );
if( !bWriteStat){
if ( GetLastError() == ERROR_IO_PENDING ) {
WaitForSingleObject( m_OverlappedWrite.hEvent, 1000 );
return dwBytesWritten;
}
return 0;
}
return dwBytesWritten;
}
//CloseHandle:關閉串口
void CSerial::Close(){
if(m_hComDev!=NULL){
if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
CloseHandle( m_hComDev );
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -