谢欣伦 - 化繁为简系列原创教程 - 通信专题 - 串口类CxSerial

  这是一个精练的串口类,类名、函数名和变量名均采用匈牙利命名法。小写的x代表我的姓氏首字母(谢欣伦),个人习惯而已,如有雷同,纯属巧合。

串口类CxSerial的使用如下(以某个叫做CSomeClass的类的相关代码为例):

一、声明串口对象实例。

CxSerial m_xComm;

二、打开串口。

三、配置串口(可选)。通常配置波特率、奇偶校验位、停止位等。

四、设置串口(可选)。通常设置缓冲区大小、接收阈值等。

五、设置串口接收缓冲区事件通知方式。消息响应或回调函数,任选其一。

六、侦听串口。

BOOL CSomeClass::OpenCommPort(LPCSTR lpszCommPort, DWORD dwBitrate)

{

    BOOL bRet = m_xComm.Open(lpszCommPort, sizeof(SOME_DATA_STRUCT)); if (bRet)

    {

        DCB dcb = {0};

        m_xComm.GetSettings(&dcb);

        dcb.BaudRate = dwBitrate;

        dcb.ByteSize = 8;

        dcb.Parity   = NOPARITY;

        dcb.StopBits = ONESTOPBIT;

        m_xComm.SetSettings(&dcb); m_xComm.SetWndMsgProc(GetSafeHwnd(), WM_SERIAL_EVENT, NULL, 0);

    }

    else

    {

        TCHAR szDebug[MAX_PATH];

        _stprintf(szDebug, _T("Open %s failed. err code [%d].\n"),

                    lpszCommPort, ::GetLastError());

        OutputDebugString(szDebug);

    }

    

    return bRet;

}

七、处理消息响应或函数回调。
1.消息响应

BEGIN_MESSAGE_MAP(CSomeClass, CStatic)

    //{{AFX_MSG_MAP(CSomeClass)

    ON_WM_DESTROY()

    //}}AFX_MSG_MAP

    ON_MESSAGE(WM_SERIAL_EVENT, OnCommEvent)

END_MESSAGE_MAP()



/////////////////////////////////////////////////////////////////////////////

// CSomeClass message handlers



LRESULT CSomeClass::OnCommEvent(WPARAM wParam, LPARAM lParam)

{

    LRESULT lRet = 0;

    switch (lParam)

    {

        case EV_RXCHAR:

            lRet = OnCommRead(wParam, lParam);

            break;

        default: break;

    }

    

    return lRet;

}



LRESULT CSomeClass::OnCommRead(WPARAM wParam, LPARAM lParam)

{// may not be more than SetRThreshold, due to a delay message coming
LRESULT lRet = 0; TCHAR szDebug[MAX_PATH], szComm[FIX_SERIALCOMM]; if ((HANDLE)wParam == m_xComm.GetSafeHandle()) { int nSize = sizeof(SOME_DATA_STRUCT); DWORD dwInQue, dwOutQue; if (!m_xComm.GetBufferCount(&dwInQue, &dwOutQue)) return lRet; m_xComm.GetCommPort(szComm); while (dwInQue >= nSize) { _stprintf(szDebug, _T("%s dwInQue=%d, dwOutQue=%d\n"), szComm, dwInQue, dwOutQue); OutputDebugString(szDebug); SOME_DATA_STRUCT data = {0}; if (m_xComm.Receive((LPBYTE)&data, nSize))
       {
  //do something with data;
       }

if
(!m_xComm.GetBufferCount(&dwInQue, &dwOutQue)) return lRet; } lRet = 1; } return lRet; }

2.回调函数

LRESULT CALLBACK CSomeClass::CommProc(LPVOID lpParam, WPARAM wParam, LPARAM lParam)

{

    LRESULT lRet = 0;

    CSomeClass* pThis = (CSomeClass*)lpParam;

    if (pThis != NULL)

        lRet = pThis->OnCommEvent(wParam, lParam);



    return lRet;

}

注意,在使用回调函数时应设置串口接收缓冲区事件通知方式为回调函数,并且设法把this指针传入设置函数,方便在回调函数中调用成员函数。

m_xComm.SetWindowMessage(NULL, 0, CommProc, (LPVOID)this);

八、关闭串口。

BOOL CSomeClass::CloseCommPort()

{

    return m_xComm.Close();

}

  至于串口数据发送,很简单,在需要处调用以下函数:

m_xComm.Send((LPBYTE)pData, sizeof(SOME_DATA_STRUCT));

   精练的代码不需要过多解释,你们懂的。To be continued...

下载

Sample using libComm - v1.1 For WinXP

libComm - v1.2 For WinXP/Win7

你可能感兴趣的:(RIA)