我寫的串口同步通信類------適合初學者

来源:互联网 发布:php 分割二维数组 编辑:程序博客网 时间:2024/03/29 22:27
/*-----------------------Developed by Nefarian Zhu Version 1.00 for Alpha LTDAll rights reserved .QQ 909990295 ------------------------*/#ifndef H_H_CSERIALPORT#define H_H_CSERIALPORT#include <iostream>#include <windows.h>#include <process.h>//Define function pointertypedef void(*pFunction)(void);  class CSerialPort{                         private:    HANDLE       m_hCom, m_hEvent;    DCB          m_dcb;    COMMTIMEOUTS m_to;    COMSTAT      m_comStat;    DWORD        m_dwRead, m_dwWrite;     DWORD        m_inBufSize, m_outBufSize;    pFunction    m_pDelegateFunc;    BOOL         m_bCloseCom;    BOOL         m_bThreadRunning;    private:    template <class ToType, class FromType>    void GetMemberFuncAddr_VC6(ToType& addr,FromType f);                void static ThreadProc(void *pThis);           public:    CSerialPort();    ~CSerialPort();    BOOL ScanComs(char *pPortsName);    BOOL Open(LPCTSTR lpCom = "COM1");    BOOL Setting(LPCTSTR lpConfig = "9600,n,8,1");    BOOL SetBufferSize(DWORD cbInQue = 512, DWORD cbOutQue = 512);    BOOL SetCommTimeouts(DWORD dwReadTimeOut = 100,                          DWORD dwWriteTimeOut = 100);    BOOL Read(LPVOID lpBuffer);    BOOL Write(LPVOID lpBuffer,DWORD nNumberOfBytesToWrite);    BOOL Close();    template <class FromType>     void BindDelegateFunc(FromType f);                                                  };                    CSerialPort::CSerialPort() {     m_hCom   = NULL;     m_hEvent = CreateEvent(NULL, true, false, NULL);     memset(&m_dcb, 0, sizeof(DCB));     memset(&m_to, 0, sizeof(COMMTIMEOUTS));      memset(&m_comStat, 0, sizeof(COMSTAT));      m_dwRead = 0;     m_dwWrite = 0;        m_inBufSize = 512;     m_outBufSize = 512;         m_pDelegateFunc = NULL;      m_bCloseCom = FALSE;     m_bThreadRunning = FALSE;}CSerialPort::~CSerialPort() {     if (m_hCom != NULL)          Close();                       }//Function to get address of member function in classtemplate <class ToType, class FromType>void CSerialPort::GetMemberFuncAddr_VC6(ToType& addr,FromType f){    union     {        FromType _f;        ToType   _t;    }ut;    ut._f = f;    addr = ut._t;      }             //Get all local host coms from RegeditBOOL CSerialPort::ScanComs(char *pPortsName){     HKEY hkey = 0;     RegOpenKeyEx(HKEY_LOCAL_MACHINE,     "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_READ, &hkey);        DWORD dIndex            = 0;     DWORD dwNameRead        = 128;      DWORD dwValuRead        = 128;     char szName[128]        = "";              char szValue[128]       = "";     short sIndex            = 0;               while (RegEnumValue(hkey, dIndex++, szName,            &dwNameRead, NULL, NULL,            (LPBYTE)szValue, &dwValuRead) == ERROR_SUCCESS)     {           strcat(pPortsName, szValue);          strcat(pPortsName, "\n");          memset(szValue, 0, sizeof(szValue));         dwValuRead = 128;     }}            //Open specified comBOOL CSerialPort::Open(LPCTSTR lpCom){     m_hCom = CreateFile(lpCom, GENERIC_READ | GENERIC_WRITE,             0, 0, OPEN_EXISTING, 0, 0);       if (m_hCom == INVALID_HANDLE_VALUE)     {          return FALSE;              }      else     {          return TRUE;     }}//Set com (baudrate,parity,stopbits)BOOL CSerialPort::Setting(LPCTSTR lpConfig){     BuildCommDCB(lpConfig, &m_dcb);     SetCommState(m_hCom,&m_dcb); }//Set com IO buff sizeBOOL CSerialPort::SetBufferSize(DWORD cbInQue, DWORD cbOutQue){     m_inBufSize = cbInQue;     m_outBufSize = cbOutQue;     SetupComm(m_hCom, m_inBufSize, m_outBufSize);}//Set com IO time for timeoutBOOL CSerialPort::SetCommTimeouts(DWORD dwReadTimeOut, DWORD dwWriteTimeOut){     m_to.ReadTotalTimeoutConstant  = dwReadTimeOut;     m_to.WriteTotalTimeoutConstant = dwWriteTimeOut;      ::SetCommTimeouts(m_hCom, &m_to);                 }//Read com from output buffBOOL CSerialPort::Read(LPVOID lpBuffer){    DWORD dwError = 0;    ClearCommError(m_hCom, &dwError, &m_comStat);        if ( (m_comStat.cbInQue == 0) || (dwError != 0) )    {         return FALSE;    }        ReadFile(m_hCom, lpBuffer, m_comStat.cbInQue, &m_dwRead, NULL);                 }//Write data to input buffBOOL CSerialPort::Write(LPVOID lpBuffer,DWORD nNumberOfBytesToWrite){     WriteFile(m_hCom, lpBuffer, nNumberOfBytesToWrite, &m_dwWrite, NULL);}//Close comBOOL CSerialPort::Close(){     if (m_bThreadRunning == TRUE)     {         m_bCloseCom = TRUE;         WaitForSingleObject(m_hEvent, 2000);     }          CloseHandle(m_hCom);}//Bind fuction to deal with RX_CHAR eventtemplate <class FromType>void CSerialPort::BindDelegateFunc(FromType f){             DWORD dwAddr = 0;                   GetMemberFuncAddr_VC6(dwAddr, f);     assert(dwAddr != 0);     m_pDelegateFunc = (pFunction)dwAddr;     _beginthread(ThreadProc,0,this);                  }        //Thread proc for RX_CHARvoid CSerialPort::ThreadProc(void *pThis){               CSerialPort *pCSerialPort = (CSerialPort*)pThis;      pCSerialPort->m_bThreadRunning = TRUE;           while (TRUE)     {                            if (pCSerialPort->m_bCloseCom == TRUE)         {              SetEvent(pCSerialPort->m_hEvent);               pCSerialPort->m_bThreadRunning = FALSE;                      return;                  }                   DWORD dwError = 0;         ClearCommError(pCSerialPort->m_hCom, &dwError, &pCSerialPort->m_comStat);                   if ( (pCSerialPort->m_comStat.cbInQue == 0) || (dwError != 0) )         {              Sleep(10);              continue;         }           else         {                                    pCSerialPort->m_pDelegateFunc();           }        }    }               #endif      /*-----H_H_CSERIALPORT-----*/