一个串口组件类

网上这方面三方类多如牛毛,真不知道用哪个好,不过不管用哪个,一定要在严格检查完善后再使用,不然给以后通信埋下隐患,只会让以后的调试会更痛苦!

ComAccess.h

 

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

//  

// ComAccess.h: interface for the CComAccess class.  

//  

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

#if !defined(AFX_COMACCESS_H__F15FFC6E_D059_4E57_97CD_A672C05FF9B7__INCLUDED_)  

#define AFX_COMACCESS_H__F15FFC6E_D059_4E57_97CD_A672C05FF9B7__INCLUDED_  

#if _MSC_VER > 1000  

#pragma once  

#endif // _MSC_VER > 1000  

class CComAccess   

{  

private:  

    HANDLE      m_hCom; // Device handle   

    OVERLAPPED  m_ov;   // A structure that contains informations which are  

                        // used for asynchronous input and output operations  

    TCHAR       m_lpszErrorMessage[256];  

public:  

    CComAccess();  

    CComAccess(LPCSTR lpszPortNum);  

    ~CComAccess();  

                                    // For more definitions see <winbase.h>  

    BOOL    Open(LPCSTR lpszPortNum = "com1",  

                 DWORD  dwBaudRate  = CBR_9600,   

                 BYTE   byParity    = NOPARITY,  

                 BYTE   byStopBits  = ONESTOPBIT,  

                 BYTE   byByteSize  = 8);  

    VOID    Close();  

    DWORD   WriteData(LPCVOID pdata, DWORD len);  

    DWORD   ReadData(LPVOID  pdest, DWORD len, DWORD dwMaxWait = 500);  

    LPSTR   GetErrorMessage(VOID) { return m_lpszErrorMessage; }  

private:  

    VOID    ErrorToString(LPCSTR lpszMessage);  

    BOOL    IsNT(VOID);  

};  

#endif // !defined(AFX_COMACCESS_H__F15FFC6E_D059_4E57_97CD_A672C05FF9B7__INCLUDED_) 

ComAccess.cpp

 

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

//  

// ComAccess.cpp: implementation of the CComAccess class.  

//  

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

#include "stdafx.h"  

#include "ComAccess.h"  

#ifdef _DEBUG  

#undef THIS_FILE  

static char THIS_FILE[]=__FILE__;  

#define new DEBUG_NEW  

#endif

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

// Construction/Destruction  

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

CComAccess::CComAccess(VOID)  

{  

    m_hCom = 0;  

    m_lpszErrorMessage[0] = ‘/0‘;  

    ZeroMemory(&m_ov, sizeof(m_ov));  

}  

CComAccess::CComAccess(LPCSTR lpszPortNum)  

{   

    CComAccess::CComAccess();  

    CComAccess::Open(lpszPortNum);   

}  

CComAccess::~CComAccess()  

{  

    Close();  

}  

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

//   

//  Function:      Open(LPCSTR lpszPortNum,  

//                      DWORD  dwBaudRate,   

//                      BYTE   byParity,  

//                      BYTE   byStopBits,  

//                      BYTE   byByteSize)  

//  

//  Return value:  BOOL TRUE or FALSE  

//  

BOOL CComAccess::Open(LPCSTR lpszPortNum,   

                     DWORD  dwBaudRate,   

                     BYTE   byParity,  

                     BYTE   byStopBits,  

                     BYTE   byByteSize)  

{  

    DCB  dcb; // structure that defines the control setting for a serial communications device  

    BOOL bSuccess;  

    m_hCom = CreateFile(lpszPortNum,           // pointer to name of the file  

                        GENERIC_READ|GENERIC_WRITE, // access mode  

                        0,                     // comm devices must be opened w/exclusive-access   

                        NULL,                  // no security attributs   

                        OPEN_EXISTING,         // comm devices must use OPEN_EXISTING   

                        FILE_FLAG_OVERLAPPED,  // overlapped I/O  

                        NULL);                 // hTemplate must be NULL for comm devices   

    if ( m_hCom == INVALID_HANDLE_VALUE )   

    {  

        // handle the error  

        CComAccess::ErrorToString("Open(): CreateFile() failed, invalid handle value");  

        return FALSE;  

    }  

    //  

    // Omit the call to SetupComm to use the default queue sizes.  

    // Get the current configuration.  

    //  

    bSuccess = GetCommState(m_hCom, &dcb);  

    if ( ! bSuccess )   

    {  

        // Handle the error.  

        CComAccess::ErrorToString("Open(): GetCommState() failed");  

        CComAccess::Close();  

        return FALSE;  

    }  

    //  

    // Fill in the DCB: baud=9600, 8 data bits, no parity, 1 stop bit are default parameters  

    //  

    dcb.BaudRate = dwBaudRate;  

    dcb.ByteSize = byByteSize;  

    dcb.Parity   = byParity;  

    dcb.StopBits = byStopBits;  

    bSuccess = SetCommState(m_hCom, &dcb);  

    if ( ! bSuccess )   

    {  

        // Handle the error.   

        CComAccess::ErrorToString("Open(): SetCommState() failed");  

        CComAccess::Close();  

        return FALSE;  

    }  

    return TRUE;  

}  

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

//   

//  Function:      Close(VOID)  

//  

//  Return value:  VOID  

//  

VOID CComAccess::Close()  

{  

    if ( m_hCom > 0 )  

    {  

        CloseHandle(m_hCom);  

    }  

    m_hCom = 0;   

}  

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

//   

//  Function:     WriteData(LPCVOID pdata,   

//                          DWORD   len)  

//  

//  Return value:  DWORD -1 failed, above, num written bytes  

//  

DWORD CComAccess::WriteData(LPCVOID pdata,   

                           DWORD   len)  

{  

    BOOL  bSuccess;  

    DWORD written = 0;  

    if ( len < 1 )  

        return(0);  

    // create event for overlapped I/O  

    m_ov.hEvent = CreateEvent(NULL,   // pointer to security attributes   

                              FALSE,   // flag for manual-reset event   

                              FALSE,  // flag for initial state   

                              "");    // pointer to event-object name   

    if ( m_ov.hEvent == INVALID_HANDLE_VALUE )  

    {  

        // Handle the error.  

        CComAccess::ErrorToString("WriteData(): CreateEvent() failed");  

        return(-1);  

    }  

    bSuccess = WriteFile(m_hCom,   // handle to file to write to    

                         pdata,    // pointer to data to write to file   

                         len,      // number of bytes to write   

                         &written, // pointer to number of bytes written   

                         &m_ov);   // pointer to structure needed for overlapped I/O  

    if ( CComAccess::IsNT() )  

    {  

        bSuccess = GetOverlappedResult(m_hCom, &m_ov, &written, TRUE);  

        if ( ! bSuccess )  

        {  

            // Handle the error.  

            CloseHandle(m_ov.hEvent);  

            CComAccess::ErrorToString("WriteData(): GetOverlappedResult() failed");  

            return(-1);  

        }  

    }  

    else  

    if ( len != written )  

    {  

        // Handle the error.  

        CloseHandle(m_ov.hEvent);  

        CComAccess::ErrorToString("WriteData(): WriteFile() failed");  

        return(-1);  

    }  

    CloseHandle(m_ov.hEvent);  

    return written;  

}  

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

//   

//  Function:      ReadData(LPVOID pdest,   

//                          DWORD  len,   

//                          DWORD  dwMaxWait)  

//  

//  Return value:  DWORD -1 failed, above, num read bytes         

//  

DWORD CComAccess::ReadData(LPVOID pdest,   

                          DWORD  len,   

                          DWORD  dwMaxWait)  

{  

    BOOL  bSuccess;  

    DWORD result = 0,  

          read   = 0, // num read bytes  

          mask   = 0; // a 32-bit variable that receives a mask   

                      // indicating the type of event that occurred  

    if ( len < 1 ) return(0);  

    // create event for overlapped I/O  

    m_ov.hEvent = CreateEvent(NULL,   // pointer to security attributes   

                              FALSE,   // flag for manual-reset event   

                              FALSE,  // flag for initial state   

                              "");    // pointer to event-object name   

    if ( m_ov.hEvent == INVALID_HANDLE_VALUE )  

    {  

        // Handle the error.  

        CComAccess::ErrorToString("ReadData(): CreateEvent() failed");  

        return(-1);  

    }  

    // Specify here the event to be enabled  

    bSuccess = SetCommMask(m_hCom, EV_RXCHAR);  

    if ( ! bSuccess )  

    {  

        // Handle the error.  

        CloseHandle(m_ov.hEvent);  

        CComAccess::ErrorToString("ReadData(): SetCommMask() failed");  

        return(-1);  

    }  

    // WaitForSingleObject  

    bSuccess = WaitCommEvent(m_hCom, &mask, &m_ov);  

    if ( ! bSuccess )  

    {  

        int err = GetLastError();  

        if ( err == ERROR_IO_PENDING)  

        {  

            result = WaitForSingleObject(m_ov.hEvent, dwMaxWait);  //wait dwMaxWait  

                                                // milli seconds before returning  

            if ( result == WAIT_FAILED )  

            {  

                // Handle the error.  

                CloseHandle(m_ov.hEvent);  

                CComAccess::ErrorToString("ReadData(): WaitForSingleObject() failed");  

                return(-1);  

            }  

        }  

    }  

    // The specified event occured?  

    if ( mask & EV_RXCHAR)   

    {  

        bSuccess = ReadFile(m_hCom, // handle of file to read   

                            pdest,  // address of buffer that receives data   

                            len,    // number of bytes to read   

                            &read,  // address of number of bytes read   

                            &m_ov); // address of structure for data   

        if ( CComAccess::IsNT() )  

        {  

            bSuccess = GetOverlappedResult(m_hCom, &m_ov, &read, TRUE);  

            if ( ! bSuccess )  

            {  

                // Handle the error.  

                CloseHandle(m_ov.hEvent);  

                CComAccess::ErrorToString("WriteData(): GetOverlappedResult() failed");  

                return(-1);  

            }  

        }  

        else  

        if ( ! bSuccess )  

        {  

            // Handle the error.  

            CloseHandle(m_ov.hEvent);  

            CComAccess::ErrorToString("ReadData(): ReadFile() failed");  

            return(-1);  

        }  

    }  

    else  

    {  

        // Handle the error.  

        CloseHandle(m_ov.hEvent);  

        wsprintf(m_lpszErrorMessage, "Error ReadData(): No EV_RXCHAR occured/n");  

        return(-1);  

    }  

    CloseHandle(m_ov.hEvent);  

    return read;  

}  

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

//   

//  Function:      ErrorToString(LPCSTR lpszMessage)  

//  

//  Return value:  VOID  

//  

VOID CComAccess::ErrorToString(LPCSTR lpszMessage)  

{  

    LPVOID lpMessageBuffer;  

    DWORD  error = GetLastError();  

    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |  

                  FORMAT_MESSAGE_FROM_SYSTEM,      // source and processing options  

                  NULL,                            // pointer to message source  

                  error,                           // requested message identifie  

                  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // the user default language.  

                  (LPTSTR) &lpMessageBuffer,       // pointer to message buffer  

                  0,                               // maximum size of message buffer  

                  NULL);                           // address of array of message inserts   

    // and copy it in our error string  

    wsprintf(m_lpszErrorMessage,"%s: (%d) %s/n", lpszMessage, error, lpMessageBuffer);  

    LocalFree(lpMessageBuffer);  

}  

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

//   

//  Function:     IsNT(VOID)  

//  

//  Return value: BOOL True or False  

//  

BOOL CComAccess::IsNT(VOID)  

{  

    OSVERSIONINFO osvi;  

    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);  

    GetVersionEx(&osvi);  

    if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)   

    {  

        return TRUE;  

    }  

    else  

    {  

        return FALSE;  

    }  

}  
时间: 2024-07-31 13:39:22

一个串口组件类的相关文章

设计一个串口装饰类(1)

团队正在开发一个仪器控制软件的框架,希望该框架能兼容/容忍一些硬件的变换,以及灵活定制建立在该硬件平台之上的工作流.目标仪器使用了很多的串口通信(Serial Port),所以大家觉得应该设计/封装一个统一的串口类来管理串口通信的一致性.就我个人的意见来说,我不是建议在System.IO.Port.SerialPort上再做封装的.串口通信逻辑很简单,基本就是I/O.该类已经提供了同步阻塞模型.基于事件的异步模型,各种I/O快捷方法,所以不认为封装该类可以获得什么更多好处.但是面对框架的 一些其

一个摄像机控制类的总结

一个摄像机控制类的总结 实现功能: 通过鼠标的操纵,控制摄像机环绕模型对象旋转,从而进行对模型对象的观察. 设计思路: 首先根据摄像机的当前方位,计算它应该到达的目标方位: 然后通过插值运算,将摄像机逐帧移动到该目标方位. 过程描述: 1. 计算摄像机的目标方位. 先计算摄像机本地坐标系轴向与世界坐标系轴向的夹角,作为方位的初始值.注意,这里只取摄像机需要旋转变化的坐标轴即可,这里我们用的是X和Y轴. 在鼠标的控制过程中,实时的修改此夹角值. 对修改后的夹角值进行限位处理,使之满足我们的需要.

第三方组件引用另一个第三方组件的悲剧

首先我先声明,我的摘要是故意这样写的,如果你是因为看了摘要才进来的,请让我大笑三声:哈哈哈~~ 不过既然你已经进来了,不妨继续往下看看~~ 事件背景 话说最近换工作了,刚接手的项目的项目中遇到一个棘手的事情;一个第三方组件中使用了老版的log4net(1.2.10),另一个第三方组件中使用了新版的log4net(1.2.13) 这下问题来了 当我自己的项目中需要同时使用这2个第三方组件的时候,他们各自引用的log4net版本是不一致的 所以,不管我引用的是哪个版本的log4net,最终的效果是另

react组件 -- React.createClass()方法--同时创建多个组件类

<!DOCTYPE html><html> <head> <script src="../build/react.js"></script> <script src="../build/react-dom.js"></script> <script src="../build/browser.min.js"></script> </h

C#异步数据接收串口操作类

C#异步数据接收串口操作类 使用C#调用传统32位API实现串口操作,整个结构特别的简单.接收数据只需要定义数据接收事件即可. 上传源代码我不会,需要源代码的请与我([email protected])联系.你也可以教我怎么上传源代码. using System; using System.Runtime.InteropServices; /// <summary> /// (C)2003-2005 C2217 Studio  保留所有权利 /// /// 文件名称:     IbmsSeri

VC 串口通信类

为了节省时间,我就贴出来吧 头文件 SerialPort.h 1 /*************************************************************************************************** 2 * SerialPort.h 3 * 4 * 功 能:串口通讯类 5 * 类 名:CSerialPort 6 * 7 * Ver 变更日期 负责人 变更内容 8 * ───────────────────────────────

我写的一个ExcelHelper通用类,可用于读取或生成数据

读取或生成EXCEL数据的方法有很多,一般常见的有: 1.通过OFFICE EXCEL组件,优点:读取与生成EXCEL文件方便,缺点:服务器上必须安装OFFICE软件,且进程无法及时释放 2.通过第三方组件(比如:NPOI),优点:无需安装OFFICE软件,缺点:需要引入第三方组件,当然这个还是比较强的 3.通过把EXCEL当成数据库,连接后运用SQL语句读取,写入的话就自行拼接成HTML表格,优点:无需另外的组件,缺点:需要会SQL及拼接HTML表格较麻烦: 三种方法我都有用过,若开发BS网站

Spring自定义一个拦截器类SomeInterceptor,实现HandlerInterceptor接口及其方法的实例

利用Spring的拦截器可以在处理器Controller方法执行前和后增加逻辑代码,了解拦截器中preHandle.postHandle和afterCompletion方法执行时机. 自定义一个拦截器类SomeInterceptor,实现HandlerInterceptor接口及其方法. 然后在spring-mvc.xml中添加拦截器配置,来指定拦截哪些请求. 步骤一: 创建SomeInterceptor拦截器组件 新建一个com.souvc.interceptor包,在该包中新建一个SomeI

Swing学习笔记1-----Swing组件类的层次

1.  从结构上划分 Swing 组件类分为两种,一种是JComponent类,一种是Windows类.其中windows类包含的是一些可以独立显示的组件,而JComponent类包含的是不可以独立显示的组件. 什么是可独立显示的组件和不可独立显示的组件? 可独立显示的组件:当运行一个程序时,可独立显示的组件无需在其他组件上即可显示,即它可以直接显示出来,例如JFrame类. 不可独立显示的组件:运行时,必须依靠可独立显示的组件才能将其显示出来,如JLabel类,JButton类,得托付在类似于