⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 comm32.cpp

📁 电缆故障监控系统
💻 CPP
字号:
#include "stdafx.h"

#include "comm32.h"
#include "resource.h"

const short MAXBLOCK=1024;	// 串口每次读入数据的最大长度

unsigned char  InDataBuf[1024];		// 串口缓冲区
int            InDataLen;			// 串口缓冲区中实际数据长度
bool           bPoll=FALSE;
// global stuff
DWORD    BaudTable[] =
         {
            CBR_110, CBR_300, CBR_600, CBR_1200, CBR_2400,
            CBR_4800, CBR_9600, CBR_14400, CBR_19200, CBR_38400,
            CBR_56000, CBR_128000, CBR_256000
         };

DWORD    ParityTable[] =
         {
            NOPARITY, EVENPARITY, ODDPARITY, MARKPARITY, SPACEPARITY
         };

DWORD    StopBitsTable[] =
         {
            ONESTOPBIT, ONE5STOPBITS, TWOSTOPBITS
         };

LRESULT NEAR CreateCommInfo(COMMINFO *pCommInfo,int nPort,int nRate)
{
   // initialize Communication info structure
   COMDEV( pCommInfo )        = 0 ;
   CONNECTED( pCommInfo )     = FALSE ;
   PORT( pCommInfo )          = nPort ; // 1
   BAUDRATE( pCommInfo )      = nRate; //CBR_1200 ;
   BYTESIZE( pCommInfo )      = 8 ;
   //FLOWCTRL( npTTYInfo )      = FC_RTSCTS ;
   FLOWCTRL( pCommInfo )      = 0 ;
   PARITY( pCommInfo )        = NOPARITY ;
   STOPBITS( pCommInfo )      = ONESTOPBIT ;
   XONXOFF( pCommInfo )       = FALSE ;		// 关闭XON和XOFF
   WRITE_OS( pCommInfo ).Offset = 0 ;
   WRITE_OS( pCommInfo ).OffsetHigh = 0 ;
   READ_OS( pCommInfo ).Offset = 0 ;
   READ_OS( pCommInfo ).OffsetHigh = 0 ;
   // create I/O event used for overlapped reads / writes
   READ_OS( pCommInfo ).hEvent = CreateEvent( NULL,    // no security
                                              TRUE,    // explicit reset req
                                              FALSE,   // initial event reset
                                              NULL ) ; // no name
   if (READ_OS( pCommInfo ).hEvent == NULL)
      return ( -1 ) ;

   WRITE_OS( pCommInfo ).hEvent = CreateEvent( NULL,    // no security
                                               TRUE,    // explicit reset req
                                               FALSE,   // initial event reset
                                               NULL) ; // no name
   if (NULL == WRITE_OS( pCommInfo ).hEvent)
   {
      CloseHandle( READ_OS( pCommInfo ).hEvent ) ;
      return ( -1 ) ;
   }
   return 1; 
} 


BOOL NEAR DestroyCommInfo(COMMINFO *pCommInfo)
{
   if (NULL == pCommInfo)
      return ( FALSE ) ;

   // force connection closed (if not already closed)

   if (CONNECTED(pCommInfo))
      CloseConnection(pCommInfo) ;

   // clean up event objects

   CloseHandle( READ_OS( pCommInfo ).hEvent ) ;
   CloseHandle( WRITE_OS( pCommInfo ).hEvent ) ;
   CloseHandle( POSTEVENT( pCommInfo ) ) ;

   return ( TRUE ) ;

} // end of DestroyTTYInfo()


BOOL NEAR OpenConnection(COMMINFO *pCommInfo,LPTHREAD_START_ROUTINE lpStartAddress)
{            
   char       szPort[ 15 ] ;
   BOOL       fRetVal ;
   HCURSOR    hOldCursor, hWaitCursor ;
   HANDLE        hCommWatchThread ;
   DWORD         dwThreadID ;
   COMMTIMEOUTS  CommTimeOuts ;

   // show the hourglass cursor
   hWaitCursor = LoadCursor( NULL, IDC_WAIT ) ;
   hOldCursor = SetCursor( hWaitCursor ) ;


   if (PORT( pCommInfo ) > MAXPORTS)
      lstrcpy( szPort, "\\\\.\\TELNET" ) ;
   else
      wsprintf( szPort, "COM%d", PORT( pCommInfo ) ) ;

   // open COMM device

   if ((COMDEV( pCommInfo ) =
      CreateFile( szPort, GENERIC_READ | GENERIC_WRITE,
                  0,                    // exclusive access
                  NULL,                 // no security attrs
                  OPEN_EXISTING,
                  FILE_ATTRIBUTE_NORMAL | 
                  FILE_FLAG_OVERLAPPED, // overlapped I/O
                  NULL )) == (HANDLE) -1 )
      return ( FALSE ) ;
   else
   {
      // get any early notifications

      SetCommMask( COMDEV( pCommInfo ), EV_RXCHAR ) ;

      // setup device buffers

      SetupComm( COMDEV( pCommInfo ), 4096, 4096 ) ;

      // purge any information in the buffer

      PurgeComm( COMDEV( pCommInfo ), PURGE_TXABORT | PURGE_RXABORT |
                                      PURGE_TXCLEAR | PURGE_RXCLEAR ) ;

      // set up for overlapped I/O
	  
      CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF ;
      CommTimeOuts.ReadTotalTimeoutMultiplier = 0 ;
      CommTimeOuts.ReadTotalTimeoutConstant = 1000 ;
      CommTimeOuts.WriteTotalTimeoutMultiplier = 0 ;
      CommTimeOuts.WriteTotalTimeoutConstant = 1000 ;
      SetCommTimeouts( COMDEV( pCommInfo ), &CommTimeOuts ) ;
   }

   fRetVal = SetupConnection(pCommInfo) ;

   if (fRetVal)
   {
      CONNECTED( pCommInfo ) = TRUE ;

      // Create a secondary thread
      // to watch for an event.

      if (NULL == (hCommWatchThread =
                      CreateThread( (LPSECURITY_ATTRIBUTES) NULL,
                                    0, 
                                    lpStartAddress,//(LPTHREAD_START_ROUTINE)CommWatchProc,
                                    (LPVOID) pCommInfo,
                                    0, &dwThreadID )))
      {
         CONNECTED( pCommInfo ) = FALSE ;
         CloseHandle( COMDEV( pCommInfo ) ) ;
         fRetVal = FALSE ;
      }
      else
      {
         THREADID( pCommInfo ) = dwThreadID ;
         HTHREAD( pCommInfo ) = hCommWatchThread ;

         // assert DTR

         EscapeCommFunction( COMDEV( pCommInfo ), SETDTR ) ;
      }
   }
   else
   {
      CONNECTED( pCommInfo ) = FALSE ;
      CloseHandle( COMDEV( pCommInfo ) ) ;
   }

   // restore cursor

   SetCursor( hOldCursor ) ;
 /*  CString str;
   COleDateTime dt=COleDateTime::GetCurrentTime();
   CFile file;
   file.Open("commlog.txt",CFile::modeNoTruncate|CFile::modeCreate|CFile::modeWrite);
   file.SeekToEnd();
   str="串口打开时间";
   str+=dt.Format("%Y-%m-%d %H:%M:%S");
	LPTSTR p;
	p=str.GetBuffer(1024); 
	file.Write(p,str.GetLength());
	str.ReleaseBuffer();

   file.Close();*/
   return ( fRetVal ) ;

} // end of OpenConnection()


BOOL NEAR SetupConnection(COMMINFO *pCommInfo)
{
   BOOL       fRetVal ;
   BYTE       bSet ;
   DCB        dcb ;

   if (NULL == pCommInfo)
      return ( FALSE ) ;

   dcb.DCBlength = sizeof( DCB ) ;

   GetCommState( COMDEV( pCommInfo ), &dcb ) ;

   dcb.BaudRate = BAUDRATE( pCommInfo ) ;
   dcb.ByteSize = BYTESIZE( pCommInfo ) ;
   dcb.Parity = PARITY( pCommInfo ) ;
   dcb.StopBits = STOPBITS( pCommInfo ) ;

   // setup hardware flow control

   bSet = (BYTE) ((FLOWCTRL( pCommInfo ) & FC_DTRDSR) != 0) ;
   dcb.fOutxDsrFlow = bSet ;
   if (bSet)
      dcb.fDtrControl = DTR_CONTROL_HANDSHAKE ;
   else
      dcb.fDtrControl = DTR_CONTROL_ENABLE ;

   bSet = (BYTE) ((FLOWCTRL( pCommInfo ) & FC_RTSCTS) != 0) ;
	dcb.fOutxCtsFlow = bSet ;
   if (bSet)
      dcb.fRtsControl = RTS_CONTROL_HANDSHAKE ;
   else
      dcb.fRtsControl = RTS_CONTROL_ENABLE ;

   // setup software flow control

   bSet = (BYTE) ((FLOWCTRL( pCommInfo ) & FC_XONXOFF) != 0) ;

   dcb.fInX = dcb.fOutX = bSet ;
   dcb.XonChar = ASCII_XON ;
   dcb.XoffChar = ASCII_XOFF ;
   dcb.XonLim = 100 ;
   dcb.XoffLim = 100 ;

   // other various settings

   dcb.fBinary = TRUE ;
   dcb.fParity = TRUE ;

   fRetVal = SetCommState( COMDEV( pCommInfo ), &dcb ) ;

   return ( fRetVal ) ;

} // end of SetupConnection()


BOOL NEAR CloseConnection( COMMINFO *pCommInfo )
{
   // set connected flag to FALSE

   CONNECTED( pCommInfo ) = FALSE ;

   // disable event notification and wait for thread
   // to halt

   SetCommMask( COMDEV( pCommInfo ), 0 ) ;

   // block until thread has been halted

   while(THREADID(pCommInfo) != 0);

   // kill the focus

   // drop DTR

   EscapeCommFunction( COMDEV( pCommInfo ), CLRDTR ) ;

   // purge any outstanding reads/writes and close device handle

   PurgeComm( COMDEV( pCommInfo ), PURGE_TXABORT | PURGE_RXABORT |
                                   PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
   CloseHandle( COMDEV( pCommInfo ) ) ;
/*   CString str;
   COleDateTime dt=COleDateTime::GetCurrentTime();
   CFile file;
   file.Open("commlog.txt",CFile::modeNoTruncate|CFile::modeCreate|CFile::modeWrite);
   file.SeekToEnd();
   str="串口关闭时间";
   str+=dt.Format("%Y-%m-%d %H:%M:%S");
	LPTSTR p;
	p=str.GetBuffer(1024); 
	file.Write(p,str.GetLength());
	str.ReleaseBuffer();

   file.Close();*/
   return ( TRUE ) ;

} // end of CloseConnection()


int NEAR ReadCommBlock(COMMINFO *pCommInfo,LPSTR lpszBlock, int nMaxLength )
{
	BOOL       fReadStat;
	COMSTAT    ComStat;
	DWORD      dwErrorFlags;
	DWORD      dwLength;
	DWORD      dwError;
//	char       szError[ 10 ];

	// only try to read number of bytes in queue 
	ClearCommError( COMDEV( pCommInfo ), &dwErrorFlags, &ComStat ) ;
	dwLength = min( (DWORD) nMaxLength, ComStat.cbInQue );

	if (dwLength > 0)
	{
		fReadStat = ReadFile( COMDEV( pCommInfo ), lpszBlock,
		                    dwLength, &dwLength, &READ_OS( pCommInfo ) ) ;
		if (!fReadStat)
		{
			if (GetLastError() == ERROR_IO_PENDING)
			{
				while(!GetOverlappedResult( COMDEV( pCommInfo ), 
					&READ_OS( pCommInfo ), &dwLength, TRUE ))
				{
					dwError = GetLastError();
					if(dwError == ERROR_IO_INCOMPLETE)
						// normal result if not finished
						continue;
					else
					{
						ClearCommError( COMDEV( pCommInfo ), &dwErrorFlags, &ComStat ) ;
						break;
					}
						
				}
					
			}
			else
			{
			    dwLength = 0 ;
				ClearCommError( COMDEV(pCommInfo ), &dwErrorFlags, &ComStat ) ;
			}
		}
	}
/*	if(dwLength>0)
	{
		CString str;
		COleDateTime dt=COleDateTime::GetCurrentTime();
		CFile file;
		file.Open("commlog.txt",CFile::modeNoTruncate|CFile::modeCreate|CFile::modeWrite);
		file.SeekToEnd();
		str="读数据时间";
		str+=dt.Format("%Y-%m-%d %H:%M:%S");
		str+="数据内容是:";
		LPTSTR p;
        p=str.GetBuffer(1024); 
		file.Write(p,str.GetLength());
        str.ReleaseBuffer();
		file.Write(lpszBlock,dwLength);
		file.Close();   
	}
*/
    return ( dwLength ) ;

} // end of ReadCommBlock()


BOOL NEAR WriteCommBlock(COMMINFO *pCommInfo,LPSTR lpByte , DWORD dwBytesToWrite)
{
	BOOL        fWriteStat ;
	DWORD       dwBytesWritten ;
	DWORD       dwErrorFlags;
	DWORD   	dwError;
	COMSTAT     ComStat;

	fWriteStat = WriteFile( COMDEV( pCommInfo ), lpByte, dwBytesToWrite,
	                       &dwBytesWritten, &WRITE_OS( pCommInfo ) ) ;
	if (!fWriteStat)
	{
		if(GetLastError() == ERROR_IO_PENDING)
		{
			while(!GetOverlappedResult( COMDEV( pCommInfo ),
				&WRITE_OS( pCommInfo ), &dwBytesWritten, TRUE ))
			{
				dwError = GetLastError();
				if(dwError == ERROR_IO_INCOMPLETE)
					continue;
				else
				{
					ClearCommError( COMDEV( pCommInfo ), &dwErrorFlags, &ComStat ) ;
					break;
				}
			}
		}
		else
		{						 	
			ClearCommError( COMDEV( pCommInfo ), &dwErrorFlags, &ComStat ) ;
			return ( FALSE );
		}
	}

/*	CString str;
	COleDateTime dt=COleDateTime::GetCurrentTime();
	CFile file;
	file.Open("commlog.txt",CFile::modeNoTruncate|CFile::modeCreate|CFile::modeWrite);
	file.SeekToEnd();
	str="写数据时间";
	str+=dt.Format("%Y-%m-%d %H:%M:%S");
	str+="数据内容是:";
	LPTSTR p;
	p=str.GetBuffer(1024); 
	file.Write(p,str.GetLength());
	str.ReleaseBuffer();
	file.Write(lpByte,dwBytesToWrite);
	file.Close(); */ 
	return ( TRUE ) ;

} // end of WriteCommBlock()

DWORD FAR PASCAL CommWatchProc( LPSTR lpData )
{
   DWORD      dwEvtMask ;
   COMMINFO   *pCommInfo = (COMMINFO*) lpData ;
   OVERLAPPED os ;
   int        nLength;

   memset( &os, 0, sizeof( OVERLAPPED ) ) ;

   // create I/O event used for overlapped read

   os.hEvent = CreateEvent( NULL,    // no security
                            TRUE,    // explicit reset req
                            FALSE,   // initial event reset
                            NULL) ;  // no name
   if (os.hEvent == NULL)
   {
      MessageBox( NULL, "Failed to create event for thread!", "TTY Error!",
                  MB_ICONEXCLAMATION | MB_OK ) ;
      return ( FALSE ) ;
   }

   if (!SetCommMask( COMDEV( pCommInfo ), EV_RXCHAR ))
      return ( FALSE ) ;

   while ( CONNECTED( pCommInfo ) )
   {
		dwEvtMask = 0 ;

		WaitCommEvent( COMDEV( pCommInfo ), &dwEvtMask, NULL );

		if ((dwEvtMask & EV_RXCHAR) == EV_RXCHAR)
		{

		   while(bPoll);
		   bPoll=TRUE;
		   do
		   {	
				if(nLength = ReadCommBlock(pCommInfo,(LPSTR)(&InDataBuf[InDataLen]),MAXBLOCK))
					InDataLen+=nLength;
		   }
		   while ( nLength > 0 );

		   bPoll=FALSE;
		}
   }// get rid of event handle

   CloseHandle( os.hEvent );
   // clear information in structure (kind of a "we're done flag")
   THREADID( pCommInfo ) = 0;
   HTHREAD( pCommInfo ) = NULL ;

   return( TRUE );
}// end of CommWatchProc()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -