evc新手入门,现有例程如下,运行后可以实现发送(1234!),请问如何实现接收PC发送的数据,请不吝赐教!
定义的串口类
CCESerial::CCESerial()
{
m_nKillRxThread = 0;
m_hSer = INVALID_HANDLE_VALUE;
m_lDatLen = 0;
}
CCESerial::~CCESerial()
{
}
DWORD WINAPI CCESerial::ReceiveThreadFunc(LPVOID lparam)
{
CCESerial *lpSerial = (CCESerial*)lparam;
DWORD dwEvtMask, dwReadError;
COMSTAT cmStat;
ULONG nWillLen;
SetCommMask( lpSerial->m_hSer, EV_RXCHAR|EV_ERR );
for( ; ; )
{
if( WaitCommEvent( lpSerial->m_hSer, &dwEvtMask, NULL ) )
{
SetCommMask( lpSerial->m_hSer, EV_RXCHAR|EV_ERR );
// get how many data available in receive buffer
if( dwEvtMask & EV_RXCHAR )
{
ClearCommError( lpSerial->m_hSer, &dwReadError, &cmStat ); //取接收数据长度信息
nWillLen = cmStat.cbInQue;
if( nWillLen <=0 )
continue;
lpSerial->m_lDatLen = 0;
ReadFile( lpSerial->m_hSer, lpSerial->DatBuf, nWillLen, &lpSerial->m_lDatLen, 0 );
if( lpSerial->m_lDatLen>0 )
{
// 调用回调函数处理接收到的数据
lpSerial->OnReceive( );
}
}
else if( dwEvtMask & EV_ERR )
{
// 清错误标志
ClearCommError( lpSerial->m_hSer, &dwReadError, &cmStat );
lpSerial->OnError( );
}
}
if( WaitForSingleObject( lpSerial->m_hKillRxThreadEvent, 0 ) == WAIT_OBJECT_0)
{
SetEvent( lpSerial->m_hReceiveCloseEvent );
break;
}
}
return 0;
}
void CCESerial::CloseReceiveThread()
{
}
BOOL CCESerial::OpenPort( UINT PortNo, UINT Baud, UCHAR Parity, UINT Databits, UINT Stopbits )
{
TCHAR szPort[20];
DCB dcb;
COMMTIMEOUTS SerTimeouts;
// 已经打开的话,直接返回
if (m_hSer != INVALID_HANDLE_VALUE)
{
return TRUE;
}
//设置串口名称
wsprintf(szPort, L"COM%d:", PortNo);
m_hSer = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
if( m_hSer == INVALID_HANDLE_VALUE)
{
return FALSE;
}
GetCommState( m_hSer, &dcb );
// Purge any pending characters in the serial port.
PurgeComm(m_hSer, (PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR));
//
// Fill in the device control block.
//
// 修改相关参数
dcb.BaudRate = Baud;
dcb.ByteSize = Databits;
switch( Parity )
{
case 'N':
case 'n':
dcb.Parity = NOPARITY;
break;
case 'O':
case 'o':
dcb.Parity = ODDPARITY;
break;
case 'E':
case 'e':
dcb.Parity = EVENPARITY;
break;
}
dcb.StopBits = ONESTOPBIT;
// Set the new serial port configuration.
// 再设置回串口驱动
SetCommState(m_hSer, &dcb);
// 读取当前超时参数结构
GetCommTimeouts( m_hSer, &SerTimeouts );
// 修改相关参数...
SerTimeouts.ReadIntervalTimeout = 4;
SerTimeouts.ReadTotalTimeoutConstant = 0;
SerTimeouts.ReadTotalTimeoutMultiplier = 0;
SerTimeouts.WriteTotalTimeoutConstant = 0;
SerTimeouts.WriteTotalTimeoutMultiplier = 0;
// 再设置回串口驱动
SetCommTimeouts( m_hSer, &SerTimeouts );
m_hReceiveCloseEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
m_hKillRxThreadEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
m_nKillRxThread = 0;
// 创建串口的接收线程
m_hReceiveThread = CreateThread( NULL,0, ReceiveThreadFunc, this, 0, NULL );
if( m_hReceiveThread == INVALID_HANDLE_VALUE)
{
CloseHandle( m_hSer );
m_hSer = INVALID_HANDLE_VALUE;
return FALSE;
}
return TRUE;
}
DWORD CCESerial::WritePort( char *Buf, int len )
{
DWORD dwLen;
// Send this character to the serial port.
dwLen = 0;
if( m_hSer==INVALID_HANDLE_VALUE )
return 0;
WriteFile( m_hSer, Buf, len, &dwLen, NULL);
return dwLen;
}
BOOL CCESerial::ClosePort()
{
BOOL bResulte;
m_nKillRxThread = 1;
SetEvent( m_hKillRxThreadEvent );
// 设置所有事件无效
SetCommMask( m_hSer, 0 );
// 清空所有将要读取的数据
PurgeComm( m_hSer, PURGE_RXCLEAR );
WaitForSingleObject( m_hReceiveCloseEvent, 2000 );
bResulte = TerminateThread( m_hReceiveThread, 0 );
m_nKillRxThread = 0;
CloseHandle( m_hSer );
m_hSer = INVALID_HANDLE_VALUE;
return TRUE;
}
主程序文件:
static void CALLBACK OnReceive( );
static void CALLBACK OnError( );
class CCESerial ceSer;
int type;
ULONG ReceiveLen;
ULONG SendLen;
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
int i1, PortNum, Baud;
BOOL bResult;
// ULONG WaitReturn;
char str[100];
// Start & Init LCD
// type = LCD_Init( LCD_12864 );
type = LCD_Init( LCD_AUTO );
if( type>0 )
{
LCD_WriteString( 8, 0, "step2 v1.0", 1 );
}
PortNum = 2;
Baud = 9600;
i1 = wcslen( lpCmdLine );
if( i1>0 )
{
wcstombs( str, lpCmdLine, i1 );
sscanf( str, "%d %d", &PortNum, &Baud );
}
printf( "PortNum: %d Baud: %d\r\n", PortNum, Baud );
bResult = ceSer.OpenPort( PortNum, Baud, 'n', 8, 1 );
if( bResult==FALSE )
return -1;
strcpy( str, "1234!" );
i1 = strlen( str );
ceSer.WritePort( str, i1 );
ceSer.OnReceive = OnReceive;
ceSer.OnError = OnError;
ReceiveLen = 0;
SendLen = 0;
for( ; ; )
{
sleep(100) ;
}
ceSer.ClosePort( );
return 0;
}
void CALLBACK OnReceive( )
{
char str[100];
DWORD dwlen;
ReceiveLen += ceSer.m_lDatLen;
dwlen = ceSer.WritePort( ceSer.DatBuf, ceSer.m_lDatLen );
SendLen += dwlen;
if( type>0 )
{
sprintf( str, "RCV: %ld ", ReceiveLen );
LCD_WriteString( 8, 16, str, 1 );
sprintf( str, "Send: %ld ", SendLen );
LCD_WriteString( 8, 32, str, 1 );
}
}
void CALLBACK OnError( )
{
if( type>0 )
{
LCD_WriteString( 8, 32, "Serial Err!", 1 );
}
}