rs232.cpp
上传用户:gelin96
上传日期:2017-01-08
资源大小:20993k
文件大小:8k
源码类别:

MTK

开发平台:

C++ Builder

  1. //#include  "StdAfx.h"
  2. #include <process.h>    /* _beginthread, _endthread */
  3. #include <assert.h>
  4. #include "string.h"
  5. #include "stdio.h"
  6. #include  "rs232.h"
  7. //=============================================================================
  8. #define RXQUEUESIZE     4096
  9. #define TXQUEUESIZE     4096
  10. //=============================================================================
  11. CRS232::CRS232(void)
  12. {
  13.     m_bConnected = false;
  14.     pos_write = 0;
  15.     pos_read  = 0;
  16.     pos_wrap  = UART_WRAPPOS;
  17.     LogEnable = true;
  18. //   LogEnable = false;
  19.     LogString[0]=0;
  20.     m_PortNo = 0;
  21.     memset(&m_osWrite, 0, sizeof(OVERLAPPED));
  22.     memset(&m_osRead, 0, sizeof(OVERLAPPED));
  23.     m_osRead.hEvent  = CreateEvent(NULL,  TRUE, FALSE, NULL);
  24.     m_osWrite.hEvent = CreateEvent(NULL,  TRUE, FALSE, NULL);
  25. /* for thread handle :
  26.    memset( ThreadBuffer, 0, sizeof(ThreadBuffer));
  27.    m_hThread        =  CreateEvent( NULL, FALSE, FALSE, NULL  );
  28. */
  29. }
  30. //-----------------------------------------------
  31. CRS232::~CRS232(void)
  32. {
  33.     if (m_bConnected)
  34.     {
  35.         Close();
  36.     }
  37.     CloseHandle(m_osRead.hEvent);
  38.     CloseHandle(m_osWrite.hEvent);
  39. /* for thread handle :
  40.    CloseHandle(  m_hThread   );
  41. */
  42. }
  43. //-----------------------------------------------
  44. /*
  45.    CreatFile --> SetCommState --> SetCommMask --> SetupComm --> SetCommTimeouts --> _beginthread
  46. */
  47. bool CRS232::Open(int port_no, long baudrate, int data_bit, int stop_bit, int parity,int ena_dts_rts, int ena_rts_cts, int ena_xon_xoff)
  48. {
  49.     char szComPort[] = "\\.\COM99";
  50.     DWORD dwBaudRate = (DWORD)baudrate;
  51.     BYTE cByteSize   = (BYTE)data_bit;
  52.     BYTE cStopBits   = (BYTE)stop_bit;
  53.     BYTE cParity     = (BYTE)parity;
  54.     bool bDTR_DSR    = (bool)(ena_dts_rts!=0);
  55.     bool bRTS_CTS    = (bool)(ena_rts_cts!=0);
  56.     bool bXON_XOFF   = (bool)(ena_xon_xoff!=0);
  57.     int ok;
  58.     if (m_bConnected )
  59.       return  FALSE;
  60.    if(port_no<10)
  61.    {  szComPort[7] = '0'+port_no;
  62.       szComPort[8] = 0;
  63.    }
  64.    else
  65.    {  szComPort[7] = '0'+port_no/10;
  66.       szComPort[8] = '0'+port_no%10;
  67.       szComPort[9] = 0;
  68.    }
  69.    m_PortNo = port_no;
  70.    SetEvent(m_osWrite.hEvent);
  71.    m_hPort  =  CreateFile( szComPort, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0/*FILE_FLAG_OVERLAPPED*/,  NULL );
  72.    if( m_hPort==INVALID_HANDLE_VALUE )
  73.       return  FALSE;
  74.    DCB  dcb;
  75.    dcb.DCBlength    =  sizeof(DCB);
  76.    GetCommState( m_hPort,&dcb );
  77.    dcb.BaudRate     = dwBaudRate;
  78.    dcb.ByteSize     = cByteSize;
  79.    dcb.Parity       = cParity;
  80.    dcb.StopBits     = cStopBits;
  81.    dcb.fOutxDsrFlow = (bDTR_DSR!=0);
  82.    dcb.fDtrControl  = (bDTR_DSR) ? DTR_CONTROL_HANDSHAKE : DTR_CONTROL_ENABLE;
  83.    dcb.fOutxCtsFlow = (bRTS_CTS!=0);
  84.    dcb.fRtsControl  = (bRTS_CTS)  ? RTS_CONTROL_HANDSHAKE : RTS_CONTROL_ENABLE;
  85.    dcb.fInX         = (bXON_XOFF!=0);
  86.    dcb.fOutX        = (bXON_XOFF!=0);
  87.    dcb.fBinary      = TRUE  ;
  88.    dcb.fParity      = TRUE  ;
  89.    ok = SetCommState(m_hPort,&dcb);
  90.    if(!ok)
  91.    {  m_bConnected =  FALSE  ;
  92.       CloseHandle( m_hPort )  ;
  93.       return  FALSE;
  94.    }
  95.    SetCommMask( m_hPort, EV_RXCHAR|EV_TXEMPTY );
  96.    SetupComm(m_hPort, RXQUEUESIZE /*InQueue size*/ , TXQUEUESIZE /*OutQueue size*/);
  97.    COMMTIMEOUTS CommTimeOuts  ;
  98.    CommTimeOuts.ReadIntervalTimeout         =  MAXDWORD;
  99.    CommTimeOuts.ReadTotalTimeoutMultiplier  =  0;
  100.    CommTimeOuts.ReadTotalTimeoutConstant    =  0;
  101.    CommTimeOuts.WriteTotalTimeoutMultiplier =  0;
  102.    CommTimeOuts.WriteTotalTimeoutConstant   =  0;
  103.    SetCommTimeouts(  m_hPort,  &CommTimeOuts  );
  104.    pos_read = 0;
  105.    pos_write = 0;
  106.    pos_wrap = UART_WRAPPOS;
  107.    m_bConnected  =  TRUE  ;
  108. /* for thread handle :
  109.    m_hThreadOrg = (HANDLE)_beginthread( CommThreadProc, 4096, (void*)this );
  110. */
  111.    return  TRUE;
  112. }
  113. //-----------------------------------------------
  114. bool CRS232::Close( void )
  115. {
  116.    if( !m_bConnected )
  117.       return FALSE;
  118.    m_bConnected = FALSE;
  119.    m_PortNo = 0;
  120. /* for thread handle :
  121.    SetEvent(m_hThread);
  122. */
  123.    SetCommMask( m_hPort, 0 );
  124.    EscapeCommFunction( m_hPort, CLRDTR );
  125.    CloseHandle(m_hPort);
  126.    return TRUE;
  127. }
  128. //-----------------------------------------------
  129. int  CRS232::PutData2Buf( void *data, int len)
  130. {  UINT16 w = pos_write;
  131.    UINT16 r = pos_read;
  132.    UINT8 *p = (UINT8*)data;;
  133.    int n, x;
  134.    if(LogEnable)
  135.    {  LogStrPtr = LogString;
  136.       LogStrPtr += sprintf( LogStrPtr, "COM%d RX (%d) : ", (int)m_PortNo, (int)len);
  137.       for(n=0; n<len; n++)
  138.       {  LogStrPtr += sprintf( LogStrPtr, "%02X ", (int)p[n]);   }
  139.       LogStrPtr += sprintf( LogStrPtr, " n" );
  140.    }
  141.    for(n=0; n<len; n++)
  142.    {  RXBuf[w++]=*p++;
  143.       if(w==r)  break;
  144.    }
  145.    if(w>=UART_WRAPPOS)
  146.    {  pos_wrap = w;
  147.       w = 0;
  148.    }
  149.    pos_write = w;
  150.    LogRXQposition();
  151.    return(n);
  152. }
  153. //-----------------------------------------------
  154. int  CRS232::ReadUartData( void )
  155. {
  156.    COMSTAT  com_stat;
  157.    DWORD    err_flags;
  158.    DWORD    read_len = 0;
  159.    DWORD    rxlen = UART_BUFSIZE-UART_WRAPPOS;
  160.    UINT16   w = pos_write;
  161.    UINT16   r = pos_read;
  162.    int  ok,x;
  163.    ClearCommError( m_hPort, &err_flags, &com_stat);
  164.    // decide receive count shall be min( cbInQue, UartBuff spare space)
  165.    if( rxlen>com_stat.cbInQue )
  166.       rxlen = com_stat.cbInQue;
  167.    if(r>w)
  168.       if(rxlen>(DWORD)(r-w))
  169.          rxlen = r-w;
  170.    ok = ReadFile( m_hPort, (void*)(&RXBuf[w]), rxlen , &read_len , &m_osRead);
  171.    if(!ok)
  172.    {  if(GetLastError()==ERROR_IO_PENDING)
  173.          if( !GetOverlappedResult(m_hPort, &m_osRead, &rxlen, TRUE) )
  174.             ClearCommError(  m_hPort,  &err_flags,  &com_stat  );
  175.       return(0);
  176.    }
  177.    else if(read_len>0)
  178.    {  if(LogEnable)
  179.       {  LogStrPtr = LogString;
  180.          LogStrPtr += sprintf( LogStrPtr, "COM%d RX (%d) : ",(int)m_PortNo, (int)read_len);
  181.          for(DWORD n=0; n<read_len; n++)
  182.          {  LogStrPtr += sprintf( LogStrPtr, "%02X ", (int)(RXBuf[w+n]));   }
  183.          LogStrPtr += sprintf( LogStrPtr, " n" );
  184.       }
  185.       w += read_len;
  186.       if(w>UART_WRAPPOS)
  187.       {  pos_wrap = w;
  188.          w = 0;
  189.       }
  190.       pos_write = w;
  191.       LogRXQposition();
  192.    }
  193.    return(read_len);
  194. }
  195. //-----------------------------------------------
  196. int  CRS232::ReadData( void *buf, int maxlen )
  197. {  UINT16 w = pos_write;
  198.    UINT16 r = pos_read;
  199.    UINT8 *p = (UINT8*)buf;
  200.    int n,x;
  201.    ReadUartData();
  202.    for(n=0; (n<maxlen)&&(r!=w); n++)
  203.    {  p[n] = RXBuf[r++];
  204.       if(r>=pos_wrap)  r = 0;
  205.    }
  206.    pos_read = r;
  207.    return(n);
  208. }
  209. //-----------------------------------------------
  210. int CRS232::SendData( void *buf, int len )
  211. {
  212.    DWORD  write_size = 0;
  213.    DWORD  err_flags;
  214.    COMSTAT  com_stat;
  215.    int ok, n;
  216.    if( !m_bConnected )
  217.       return(0);
  218.    if( WaitForSingleObject( m_osWrite.hEvent,0 )!=WAIT_OBJECT_0 )
  219.       return(0);
  220.    ResetEvent(m_osWrite.hEvent);
  221.    ok = WriteFile( m_hPort, buf, len, &write_size, &m_osWrite);
  222.    if(!ok)
  223.    {  if( GetLastError()==ERROR_IO_PENDING  )
  224.          return(0);
  225.       ClearCommError( m_hPort, &err_flags, &com_stat ) ;
  226.       return(0);
  227.    }
  228.    if(LogEnable)
  229.    {  UINT8 *cbuf = (UINT8*)buf;
  230.       LogStrPtr = LogString;
  231.       LogStrPtr += sprintf( LogStrPtr, "COM%d TX (%d): ", (int)m_PortNo, (int)write_size);
  232.       for(unsigned n=0; n<write_size; n++)
  233.       {  LogStrPtr += sprintf( LogStrPtr, "%02X ", (int)(cbuf[n]));   }
  234.       LogStrPtr += sprintf( LogStrPtr, " n");
  235.    }
  236.    return(write_size);
  237. }
  238. //-----------------------------------------------
  239. bool  CRS232::IsConnected( void )
  240. {  return  m_bConnected;
  241. }
  242. //-----------------------------------------------
  243. bool  CRS232::IsRxDataReady( void )
  244. {  ReadUartData();
  245.    return (pos_read!=pos_write);
  246. }
  247. //-----------------------------------------------
  248. void  CRS232::LogRXQposition(void)
  249. {  int x;
  250.    if(LogEnable)
  251.    {  if(pos_write>=pos_read)
  252.         x = (int)(pos_write-pos_read);
  253.       else
  254.         x = (int)(pos_wrap-pos_read+pos_write);
  255.       LogStrPtr += sprintf( LogStrPtr, "(r,w,cnt)=(%d,%d,%d) ", (int)pos_read, (int)pos_write, x);
  256.       if(x!=0)
  257.       {  x = pos_read;
  258.          LogStrPtr += sprintf( LogStrPtr, "Data: %02X %02X %02X %02X %02X %02X %02X %02X  ",
  259.                            (int)RXBuf[x+0], (int)RXBuf[x+1], (int)RXBuf[x+2], (int)RXBuf[x+3],
  260.                            (int)RXBuf[x+5], (int)RXBuf[x+6], (int)RXBuf[x+7], (int)RXBuf[x+8] );
  261.       }
  262.       LogStrPtr += sprintf( LogStrPtr, "n");
  263.    }
  264. }