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

/*-----------------------
Developed by Nefarian Zhu 
Version 1.00 for Alpha LTD
All rights reserved .
QQ 909990295 
------------------------*/
#ifndef H_H_CSERIALPORT
#define H_H_CSERIALPORT

#include <iostream>
#include <windows.h>
#include <process.h>

//Define function pointer
typedef 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 class
template <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 Regedit
BOOL 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 com
BOOL 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 size
BOOL CSerialPort::SetBufferSize(DWORD cbInQue, DWORD cbOutQue)
{
     m_inBufSize = cbInQue;
     m_outBufSize = cbOutQue;
     SetupComm(m_hCom, m_inBufSize, m_outBufSize);
}


//Set com IO time for timeout
BOOL CSerialPort::SetCommTimeouts(DWORD dwReadTimeOut, DWORD dwWriteTimeOut)
{
     m_to.ReadTotalTimeoutConstant  = dwReadTimeOut;
     m_to.WriteTotalTimeoutConstant = dwWriteTimeOut; 
     ::SetCommTimeouts(m_hCom, &m_to);                 
}


//Read com from output buff
BOOL 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 buff
BOOL CSerialPort::Write(LPVOID lpBuffer,DWORD nNumberOfBytesToWrite)
{
     WriteFile(m_hCom, lpBuffer, nNumberOfBytesToWrite, &m_dwWrite, NULL);
}


//Close com
BOOL CSerialPort::Close()
{
     if (m_bThreadRunning == TRUE)
     {
         m_bCloseCom = TRUE;
         WaitForSingleObject(m_hEvent, 2000);
     }
     
     CloseHandle(m_hCom);
}


//Bind fuction to deal with RX_CHAR event
template <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_CHAR
void 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-----*/   


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值