CnComm多线程串口通讯类的封装实现

来源:互联网 发布:淘宝客招募贴怎么写 编辑:程序博客网 时间:2024/06/06 07:48

之前对于CnComm类库做过简单的分析,详见CnComm多线程串口通讯类解读CnComm是llbird开发的WINDOWS/WINCE 多线程串口通讯开源库,提供同步IO并发访问的支持,内存管理采用内存池技术,提供对于C++异常的支持。在实际的项目中,需要使用多个串口来收发消息,于是对于CnComm类做了简单的封装操作。

  • 实现对于CnComm串口类的封装,提供基本的接口
  • 通过串口管理类来实现对于串口的资源的管理
  • 串口管理类采用单例模式实现
  • 在VS2005下测试通过

1.串口管理类的实现,可增加为多串口的管理类

#ifndef _COMM_MANAGE_H_#define _COMM_MANAGE_H_#include "commWrapper.h"//串口管理类class CommManage{public:static CommManage* Instance();virtual ~CommManage();public:CommWrapper& commInstance(){return commInst;}protected:CommManage();CommManage(const CommManage&);CommManage& operator= (const CommManage&);public:CommWrapper commInst;private:static CommManage* _commMangeinstance;};#endif

#include "stdafx.h"#include "CommManage.h"CommManage* CommManage::_commMangeinstance = 0;//设置串口模式CommManage::CommManage(){}CommManage::~CommManage(){}CommManage* CommManage::Instance(){if(_commMangeinstance == 0){_commMangeinstance = new CommManage();}return _commMangeinstance;}

2.串口的封装实现

#ifndef _COMM_WRAPPER_H_#define _COMM_WRAPPER_H_#include "CnComm.h"//串口模块class CommWrapper{public:CommWrapper();virtual ~CommWrapper();enum StringFormat{ASCII_FORMAT=0,HEX_FORMAT=1};void initComm();void setCommWnd(HWND hwnd);bool openComm(DWORD port, DWORD baudrate);void closeComm();void sendtoDevice(CString& sendstr, int sendstrformat);void sendasciitoDevice(CString& sendstr, CnComm& _Comm);void sendhextoDevice(CString& sendstr, CnComm& _Comm);char HexChar(char c);int Str2Hex(CString str, char* data);inline void setCommParam(DWORD port,DWORD baudrate);inline bool iscommOpen();inline CnComm& getCnComm();inline DWORD getCommPort();inline DWORD getBaudrate();private:CommWrapper(const CommWrapper&);CommWrapper& operator = (const CommWrapper&);protected:CnComm commDevice;DWORD devicePort;DWORD baudRate;CnComm::BlockBuffer rxCommBuf;};CnComm& CommWrapper::getCnComm(){return this->commDevice;}DWORD CommWrapper::getCommPort(){return this->devicePort;}DWORD CommWrapper::getBaudrate(){return this->baudRate;}//获取端口号和波特率void CommWrapper::setCommParam(DWORD port,DWORD baudrate){devicePort = port;baudRate = baudrate;}//串口是否打开bool CommWrapper::iscommOpen(){return commDevice.IsOpen();}#endif

#include "stdafx.h"#include "commWrapper.h"CommWrapper::CommWrapper(){initComm();}CommWrapper::~CommWrapper(){}//初始化串口设置void CommWrapper::initComm(){static int i=1;commDevice.SetOption(commDevice.GetOption()|CnComm::EN_RX_BUFFER);devicePort=i++;baudRate = 9600;rxCommBuf.SetMinBlockSize(4096);}//设置关联消息的窗口句柄void CommWrapper::setCommWnd(HWND hwnd){commDevice.SetWnd(hwnd);}//打开串口bool CommWrapper::openComm(DWORD port, DWORD baudrate){setCommParam(port,baudrate);if (!commDevice.IsOpen()){if (!commDevice.Open(devicePort,baudRate)){TCHAR szBuf[1024];wsprintf(szBuf, _T("未能打开串口 COM%d ,请重新选择串口"), devicePort);AfxMessageBox(szBuf);return false;}}return true;}//关闭串口void CommWrapper::closeComm(){if(commDevice.IsOpen()){commDevice.Close();}}//发送串口消息void CommWrapper::sendtoDevice(CString& sendstr,int sendstrformat){if (sendstrformat == CommWrapper::ASCII_FORMAT){sendasciitoDevice(sendstr, commDevice);}else if (sendstrformat == CommWrapper::HEX_FORMAT){sendhextoDevice(sendstr, commDevice);}}//字符串形式发送void CommWrapper::sendasciitoDevice(CString& sendstr, CnComm& _Comm){if (_Comm.IsOpen() == false){return;}_Comm.FlushPort();char* buffer = new char[sendstr.GetLength()*2+1];#ifdef UNICODEint len = wcstombs(buffer, (LPCTSTR)sendstr, sendstr.GetLength());buffer[len]= 0;#elsestrcpy(buffer, (LPCTSTR)sendstr);int len = sendstr.GetLength();#endif//! 重叠模式下或者缓冲区模式下 可以不检查输出返回值,并直接输出if (_Comm.IsOverlappedMode() || _Comm.IsTxBufferMode())_Comm.Write(buffer);else{//! 阻塞非缓冲区模式 必须检查返回值,确保数据完全发送出for (int i = 0; i<len; i++ )i += _Comm.Write(buffer + i, len - i);}delete[] buffer;}//16进制形式发送void CommWrapper::sendhextoDevice(CString& sendstr, CnComm& _Comm){_Comm.FlushPort();char data[1024];int len=Str2Hex(sendstr,data);//! 重叠模式下或者缓冲区模式下 可以不检查输出返回值,并直接输出if (_Comm.IsOverlappedMode() || _Comm.IsTxBufferMode())_Comm.Write(data, len);}//char CommWrapper::HexChar(char c){if((c>='0')&&(c<='9'))return c-0x30;else if((c>='A')&&(c<='F'))return c-'A'+10;else if((c>='a')&&(c<='f'))return c-'a'+10;else return 0x10;}//将一个字符串作为十六进制串转化为一个字节数组,字节间可用空格分隔,//返回转换后的字节数组长度,同时字节数组长度自动设置。int CommWrapper::Str2Hex(CString str, char* data){int t,t1;int rlen=0;int len=str.GetLength();for(int i=0;i<len;){char l,h=str[i];if(h==' '){i++;continue;}i++;if(i>=len)break;l=str[i];t=HexChar(h);t1=HexChar(l);if((t==16)||(t1==16))break;else t=t*16+t1;i++;data[rlen]=(char)t;rlen++;}return rlen;}

3.CnComm多线程的串口类实现

CnComm串口通讯库v1.5 源码下载


1 0
原创粉丝点击