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

📄 uart.cpp

📁 这是一个VC下 开发的串口通讯类
💻 CPP
字号:
#include  "stdafx.h"
#include  <windows.h>

#include  "systemtype\bastype.h"
#include  "charque.h"
#include  "uart.h"
#include "sysfun.h"

/*!
 * <Detailed description of the method>
 * 
 * UART constructor
 *
 * @param VOID : 
 *
 * @return  : 
 */
char port[][8] =
{
	"COM1",
	"COM2",
	"COM3",
	"COM4"
};
#define CBR_76800 76800
#define CBR_115200 115200
DWORD baudRate[] =
{
	CBR_4800  ,
	CBR_9600  ,
	CBR_14400 ,
	CBR_19200 ,
	CBR_38400 ,
	CBR_57600 ,
	CBR_76800 ,
	CBR_115200,
};
BYTE Parity[] = 
{
	NOPARITY   ,//No parity 
	ODDPARITY  ,//Odd 
	EVENPARITY  //Even 
};

UART::UART( VOID )
{
	handler = NULL;
	m_bOpened = FALSE;
	memset( &overlappedRead, 0, sizeof( OVERLAPPED ) );
 	memset( &overlappedWrite, 0, sizeof( OVERLAPPED ) );

	overlappedRead.hEvent = NULL;
	overlappedRead.Offset = 0;
	overlappedRead.OffsetHigh = 0;

	overlappedWrite.hEvent = NULL;
	overlappedWrite.Offset = 0;
	overlappedWrite.OffsetHigh = 0;

	m_totalCnt=0;
	m_minCnt=0;
	m_maxCnt=0;

   return;
}

/*!
 * <Detailed description of the method>
 *
 * UART destructor
 *
 * @param VOID : 
 *
 * @return  : 
 */
UART::~UART( VOID )
{
	Close();
}

/*!
 * <Detailed description of the method>
 *
 * request that serial port is opened
 *
 * @param none
 *
 * @return BOOL  : TRUE: opened; FALSE: is not opened 
 */
BOOL UART::isOpened()
{
	return m_bOpened;
}

/*!
 * <Detailed description of the method>
 *
 * Close the serial port
 *
 * @param none
 *
 * @return VOID  : 
 */
VOID UART::Close()
{
   m_bOpened = FALSE;
	
	if ( NULL != handler)
      CloseHandle(handler);
	
	if ( NULL != overlappedRead.hEvent )
		CloseHandle ( overlappedRead.hEvent );

	if ( NULL != overlappedWrite.hEvent )
		CloseHandle ( overlappedWrite.hEvent );
}

/*!
 * Open the serial port
 *
 * @param nPort :     the port to be open
 * @param nBaudRate : the baud rate to set
 * @param nParity :   the parity to set  
 *
 * @return BOOL  : if the function succeeds,the return value is nonzero
 *                 if the function fail, the return value is zero
 */
BOOL UART::Open(INT nPort,INT nBaudRate,INT nParity)
{
	if ( TRUE == m_bOpened )
		Close();

   COMMTIMEOUTS  CommTimeOuts;
   DCB   dcb;
   DWORD errorCode;

   // create read event
   memset(&overlappedRead,0,sizeof(OVERLAPPED));
   overlappedRead.hEvent     = CreateEvent( NULL,    // no security
                                            TRUE,    // explicit reset req
                                            FALSE,   // initial event reset
                                            NULL );  // no name
   if (NULL == overlappedRead.hEvent)
      return FALSE;

   // create write event
   memset(&overlappedWrite,0,sizeof(OVERLAPPED));
   overlappedWrite.hEvent     = CreateEvent( NULL,    // no security
                                             TRUE,    // explicit reset req
                                             FALSE,   // initial event reset
                                             NULL ) ; // no name
   if (NULL == overlappedWrite.hEvent)
      return FALSE;

   // create file
   if ( INVALID_HANDLE_VALUE == (handler =
      CreateFile( port[nPort],
                   GENERIC_READ | GENERIC_WRITE,
                   0,                              // exclusive access
                   NULL,                           // no security attrs
                   OPEN_EXISTING,
                   FILE_ATTRIBUTE_NORMAL |
                   FILE_FLAG_OVERLAPPED,           // overlapped I/O
                   NULL )) )
   {
      errorCode = GetLastError();
      return FALSE;
   }

   // get any early notifications
   if ( ! SetCommMask( handler, EV_RXCHAR | EV_ERR ) )
	   return FALSE;

   // setup device buffers
   if ( ! SetupComm( handler, 4096, 4096 ) )
	   return FALSE;
	// setup device buffers larger
	//SetupComm( handler, 10240, 10240 ) ;

   // purge any information in the buffer
   if ( ! PurgeComm( handler,PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ) )
	   return FALSE;

   // set up for overlapped I/O
   CommTimeOuts.ReadIntervalTimeout        = MAXDWORD;//0xFFFFFFFF;
   CommTimeOuts.ReadTotalTimeoutMultiplier = 0 ;
   CommTimeOuts.ReadTotalTimeoutConstant   = 0;

   // CBR_19200 is approximately 2.5byte/ms. For our purposes, allow
   // double the expected time per character for a fudge factor.
   CommTimeOuts.WriteTotalTimeoutMultiplier = 50;	//2*CBR_9600/CBR_19200;	//0;
                                                   // can be zero ???????????
   CommTimeOuts.WriteTotalTimeoutConstant   = 2000;    // 5000
   SetCommTimeouts( handler, &CommTimeOuts ) ;

   if ( ! GetCommState( handler, &dcb ) )
	   return FALSE;

   dcb.DCBlength = sizeof( DCB );
   dcb.BaudRate  = baudRate[nBaudRate];
   //dcb.BaudRate  = 256000;
//   CBR_256000
 //  dcb.BaudRate  =CBR_256000;
   dcb.BaudRate  =CBR_115200;

   dcb.fBinary   = TRUE;
   dcb.fParity   = TRUE;
   dcb.ByteSize  = 8;
   dcb.Parity    = Parity[nParity];
   dcb.StopBits  = ONESTOPBIT;


   // setup hardware flow control
   dcb.fOutxDsrFlow = FALSE;
   dcb.fDtrControl = DTR_CONTROL_DISABLE ;

   dcb.fOutxCtsFlow = FALSE;
   dcb.fRtsControl = RTS_CONTROL_DISABLE ;

   dcb.fDsrSensitivity = FALSE;
   dcb.fInX = dcb.fOutX = FALSE ;
   dcb.fNull = TRUE;

   // other various settings
   if ( ! SetCommState( handler, &dcb ) )
	   return FALSE;

	m_bOpened = TRUE;

	return TRUE;
}

/*!
 *  receive interrupt service routine
 *
 *  @param  block     the buffer for saving received characters
 *  @param  blockLen  the length of the block
 *
 *  @return  the number of characters received
 */
//   DWORD    length;
//   UCHAR    block[100];
INT  UART::RxString( VOID )
{
   BOOL     readStat;
   COMSTAT  comStat;
   DWORD    erroFlag;
   DWORD    error;
   INT      reCheck;
   DWORD    length;
   UCHAR    block[100];

  //==bug,md by ywy ,when  there are multi com 
   //static long totalCnt = 0, minCnt = 0, maxCnt = 0;
   long totalCnt = 0, minCnt = 0, maxCnt = 0;
   totalCnt = m_totalCnt;
   minCnt = m_minCnt;
   maxCnt = m_maxCnt;
//--bug

   // only try to read number of bytes in queue
   ClearCommError( handler, &erroFlag, &comStat );

   length = comStat.cbInQue;

   totalCnt ++;

   // return if no characters received from UART
   if ( 0 >= length )
   {
      minCnt ++;
      return 0;
   }

   reCheck = 0;
   if (100 <= length )
   {
      maxCnt ++;
      length = 100;
      reCheck = 1;
   }

   readStat = ReadFile( handler, block, length, &length, &overlappedRead );

   if ( !readStat )
   {
      if ( ERROR_IO_PENDING == GetLastError() )
      {
         //OutputDebugString("\n\rIO Pending");

         // We have to wait for read to complete.
         // This function will timeout according to the
         // CommTimeOuts.ReadTotalTimeoutConstant variable
         // Every time it times out, check for port errors
         while ( !GetOverlappedResult( handler, &overlappedRead, &length, TRUE ) )
         {
            error = GetLastError();
            if (ERROR_IO_INCOMPLETE == error)
               // normal result if not finished
               continue;
            else
            {
               // an error occurred, try to recover
               ClearCommError(handler , &erroFlag, &comStat ) ;
               break;
            }
         }
      }
      else
      {
         // some other error occurred
         length = 0;
         ClearCommError( handler, &erroFlag, &comStat ) ;
      }
   }

   mRxCharQue.PutString(block, length);

   // save serial port receive data
	if ( gbDumpReceiveData )
	{
		//if ( RECEIVE_BUFFER_LENGTH < length )
		//	length = RECEIVE_BUFFER_LENGTH;

		DWORD len2Tail = gSerialReceiveTail - gSerialReceivePtr + 1;
		if ( len2Tail > length )
		{
			memcpy(gSerialReceivePtr,block,length);
			gSerialReceivePtr += length;
		}
		else
		{
			memcpy(gSerialReceivePtr,block,len2Tail );
			gSerialReceivePtr = gSerialReceiveHead;
			memcpy(gSerialReceivePtr,block+len2Tail,length-len2Tail);
			gSerialReceivePtr += length-len2Tail;
		}
		gSerialReceiveCount += length;
		if ( RECEIVE_BUFFER_LENGTH < gSerialReceiveCount )
			gSerialReceiveCount = RECEIVE_BUFFER_LENGTH;
	}
	// dump data if required
	// dump data if required
	m_totalCnt = totalCnt ;
    m_minCnt=minCnt ;
    m_maxCnt=maxCnt ;
   return reCheck;
   //return 1;
}

/*!
 *  Transmit a string
 *
 *  @param   string   the characters to be transmited
 *  @param   strLen   the number of characters of the string
 *
 *  @return  <code>0</code> if buffer is full, no operation,
 *           <code>1</code> if transmit success
 */
INT  UART::TxString(UCHAR* string, INT strLen)
{
   BOOL     wirteStat;
   DWORD    bytesWritten;
   DWORD    errorFlag;
   DWORD    error;
   int      bytesSent = 0;
   COMSTAT  comStat;

   wirteStat = WriteFile( handler, string, strLen,
                          &bytesWritten, &overlappedWrite ) ;

   // Note that normally the code will not execute the following
   // because the driver caches write operations. Small I/O requests
   // (up to several thousand bytes) will normally be accepted
   // immediately and WriteFile will return true even though an
   // overlapped operation was specified

   if ( !wirteStat)
   {
      if ( ERROR_IO_PENDING == GetLastError() )
      {
         // We should wait for the completion of the write operation
         // so we know if it worked or not

         // This is only one way to do this. It might be beneficial to
         // place the write operation in a separate thread
         // so that blocking on completion will not negatively
         // affect the responsiveness of the UI

         // If the write takes too long to complete, this
         // function will timeout according to the
         // CommTimeOuts.WriteTotalTimeoutMultiplier variable.
         // This code logs the timeout but does not retry
         // the write.

         while (!GetOverlappedResult( handler, &overlappedWrite, &bytesWritten, TRUE ))
         {
            error = GetLastError();
            if ( ERROR_IO_INCOMPLETE == error )
            {
               // normal result if not finished
               bytesSent += bytesWritten;
               continue;
            }
            else
            {
               ClearCommError( handler, &errorFlag, &comStat );
               break;
            }
         }
         bytesSent += bytesWritten;
      }
      else
      {
         // some other error occurred
         ClearCommError( handler, &errorFlag, &comStat );
         return 0;
      }
   }

   // save serial port transmit data
	if ( gbDumpTransmitData )
	{
		//if ( TRANSMIT_BUFFER_LENGTH < strLen )
		//	strLen -= TRANSMIT_BUFFER_LENGTH;

		int len2Tail = gSerialTransmitTail - gSerialTransmitPtr + 1;
		if ( len2Tail > strLen )
		{
			memcpy(gSerialTransmitPtr,string,strLen);
			gSerialTransmitPtr += strLen;
		}
		else
		{
			memcpy(gSerialTransmitPtr,string,len2Tail );
			gSerialTransmitPtr = gSerialTransmitHead;
			memcpy(gSerialTransmitPtr,string+len2Tail,strLen-len2Tail);
			gSerialTransmitPtr += strLen-len2Tail;
		}
		gSerialTransmitCount += strLen;
		if ( TRANSMIT_BUFFER_LENGTH < gSerialTransmitCount )
			gSerialTransmitCount = TRANSMIT_BUFFER_LENGTH;
	}
	return 1;
}

⌨️ 快捷键说明

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