第三方串口编程.docx
- 文档编号:24685267
- 上传时间:2023-05-31
- 格式:DOCX
- 页数:19
- 大小:29.26KB
第三方串口编程.docx
《第三方串口编程.docx》由会员分享,可在线阅读,更多相关《第三方串口编程.docx(19页珍藏版)》请在冰豆网上搜索。
第三方串口编程
深入浅出VC++串口编程之第三方类
2006-02-2111:
23作者:
宋宝华出处:
天极开发责任编辑:
方舟
深入浅出VC++串口编程之第三方类源代码下载
串口类
从本系列文章连载三、四可以看出,与通过WIN32API进行串口访问相比,通过MScomm这个Activex控件进行串口访问要来的方便许多,它基本上可以向用户屏蔽多线程的细节,以事件(发出OnComm消息)方式实现串口的异步访问。
尽管如此,MScomm控件的使用仍有诸多不便,譬如其发送和接收数据都要进行VARIANT类型对象与字符串的转化等。
因此,国内外许多优秀的程序员自己编写了一些串口类,使用这些类,我们将可以更方便的操作串口。
在笔者的《深入浅出Win32多线程程序设计之综合实例》(网址:
)一文中,曾向读者展示了由RemonSpekreijse编写的CSerialPort串口类,而本文将向您展示由程序员llbird编写的cnComm(中国串口?
)串口类。
llbird是一位优秀的程序员,他的代码风格简洁而紧凑,类的声明和实现都被定义在一个头文件中,使用这个类的朋友只需要在工程中包含这一头文件即可:
/*
CommBaseLibrary(WIN98/NT/2000)ver1.1
Compileby:
BC++5;C++BUILDER4,5,6,X;VC++5,6;VC.NET;GCC;
copyright(c)2004.5-2005.8llbirdwushaojian@
*/
#ifndef_CN_COMM_H_
#define_CN_COMM_H_
#pragmawarning(disable:
4530)
#pragmawarning(disable:
4786)
#pragmawarning(disable:
4800)
#include
#include
#include
//送到窗口的消息WPARAM端口号
#defineON_COM_RECEIVEWM_USER+618
#defineON_COM_CTSWM_USER+619//LPARAM1valid
#defineON_COM_DSRWM_USER+621//LPARAM1valid
#defineON_COM_RINGWM_USER+623
#defineON_COM_RLSDWM_USER+624
#defineON_COM_BREAKWM_USER+625
#defineON_COM_TXEMPTYWM_USER+626
#defineON_COM_ERRORWM_USER+627//LPARAMsaveErrorID
#defineDEFAULT_COM_MASK_EVENTEV_RXCHAR|EV_ERR|EV_CTS|EV_DSR|EV_BREAK|EV_TXEMPTY|EV_RING|EV_RLSD
classcnComm
{
public:
//------------------------------Construction-----------------------------------
//第1个参数为是否在打开串口时启动监视线程,第2个参数为IO方式阻塞方式(0)/异步重叠方式(默认)
cnComm(boolfAutoBeginThread=true,DWORDdwIOMode=
FILE_FLAG_OVERLAPPED):
_dwIOMode(dwIOMode),_fAutoBeginThread(fAutoBeginThread)
{
Init();
}
virtual~cnComm()
{
Close();
UnInit();
}
//----------------------------------Attributes----------------------------------
//判断串口是否打开
inlineboolIsOpen()
{
return_hCommHandle!
=INVALID_HANDLE_VALUE;
}
//判断串口是否打开
operatorbool()
{
return_hCommHandle!
=INVALID_HANDLE_VALUE;
}
//获得串口句炳
inlineHANDLEGetHandle()
{
return_hCommHandle;
}
//获得串口句炳
operatorHANDLE()
{
return_hCommHandle;
}
//获得串口参数DCB
DCB*GetState()
{
returnIsOpen()&&:
:
GetCommState(_hCommHandle,&_DCB)==TRUE?
&_DCB:
NULL;
}
//设置串口参数DCB
boolSetState(DCB*pdcb=NULL)
{
returnIsOpen()?
:
:
SetCommState(_hCommHandle,pdcb==NULL?
&_DCB:
pdcb)==TRUE:
false;
}
//设置串口参数:
波特率,停止位,等支持设置字符串"9600,8,n,1"
boolSetState(char*szSetStr)
{
if(IsOpen())
{
if(:
:
GetCommState(_hCommHandle,&_DCB)!
=TRUE)
returnfalse;
if(:
:
BuildCommDCB(szSetStr,&_DCB)!
=TRUE)
returnfalse;
return:
:
SetCommState(_hCommHandle,&_DCB)==TRUE;
}
returnfalse;
}
//设置串口参数:
波特率,停止位,等
boolSetState(DWORDdwBaudRate,DWORDdwByteSize=8,DWORDdwParity=
NOPARITY,DWORDdwStopBits=ONESTOPBIT)
{
if(IsOpen())
{
if(:
:
GetCommState(_hCommHandle,&_DCB)!
=TRUE)
returnfalse;
_DCB.BaudRate=dwBaudRate;
_DCB.ByteSize=(unsignedchar)dwByteSize;
_DCB.Parity=(unsignedchar)dwParity;
_DCB.StopBits=(unsignedchar)dwStopBits;
return:
:
SetCommState(_hCommHandle,&_DCB)==TRUE;
}
returnfalse;
}
//获得超时结构
LPCOMMTIMEOUTSGetTimeouts(void)
{
returnIsOpen()&&:
:
GetCommTimeouts(_hCommHandle,&_CO)==TRUE?
&_CO:
NULL;
}
//设置超时
boolSetTimeouts(LPCOMMTIMEOUTSlpCO)
{
returnIsOpen()?
:
:
SetCommTimeouts(_hCommHandle,lpCO)==TRUE:
false;
}
//设置串口的I/O缓冲区大小
boolSetBufferSize(DWORDdwInputSize,DWORDdwOutputSize)
{
returnIsOpen()?
:
:
SetupComm(_hCommHandle,dwInputSize,dwOutputSize)==TRUE:
false;
}
//关联消息的窗口句柄
inlinevoidSetWnd(HWNDhWnd)
{
assert(:
:
IsWindow(hWnd));
_hNotifyWnd=hWnd;
}
//设定发送通知,接受字符最小值
inlinevoidSetNotifyNum(DWORDdwNum)
{
_dwNotifyNum=dwNum;
}
//线程是否运行
inlineboolIsThreadRunning()
{
return_hThreadHandle!
=NULL;
}
//获得线程句柄
inlineHANDLEGetThread()
{
return_hThreadHandle;
}
//设置要监视的事件,打开前设置有效
voidSetMaskEvent(DWORDdwEvent=DEFAULT_COM_MASK_EVENT)
{
_dwMaskEvent=dwEvent;
}
//获得读缓冲区的字符数
intGetInputSize()
{
COMSTATStat;
DWORDdwError;
return:
:
ClearCommError(_hCommHandle,&dwError,&Stat)==TRUE?
Stat.cbInQue:
(DWORD)-1L;
}
//----------------------------------Operations----------------------------------
//打开串口缺省9600,8,n,1
boolOpen(DWORDdwPort)
{
returnOpen(dwPort,9600);
}
//打开串口缺省baud_rate,8,n,1
boolOpen(DWORDdwPort,DWORDdwBaudRate)
{
if(dwPort<1||dwPort>1024)
returnfalse;
BindCommPort(dwPort);
if(!
OpenCommPort())
returnfalse;
if(!
SetupPort())
returnfalse;
returnSetState(dwBaudRate);
}
//打开串口,使用类似"9600,8,n,1"的设置字符串设置串口
boolOpen(DWORDdwPort,char*szSetStr)
{
if(dwPort<1||dwPort>1024)
returnfalse;
BindCommPort(dwPort);
if(!
OpenCommPort())
returnfalse;
if(!
SetupPort())
returnfalse;
returnSetState(szSetStr);
}
//读取串口dwBufferLength个字符到Buffer返回实际读到的字符数可读任意数据
DWORDRead(LPVOIDBuffer,DWORDdwBufferLength,DWORDdwWaitTime=10)
{
if(!
IsOpen())
return0;
COMSTATStat;
DWORDdwError;
if(:
:
ClearCommError(_hCommHandle,&dwError,&Stat)&&dwError>0)
{
:
:
PurgeComm(_hCommHandle,PURGE_RXABORT|PURGE_RXCLEAR);
return0;
}
if(!
Stat.cbInQue)
//缓冲区无数据
return0;
unsignedlonguReadLength=0;
dwBufferLength=dwBufferLength>Stat.cbInQue?
Stat.cbInQue:
dwBufferLength;
if(!
:
:
ReadFile(_hCommHandle,Buffer,dwBufferLength,&uReadLength,&_ReadOverlapped))
{
if(:
:
GetLastError()==ERROR_IO_PENDING)
{
WaitForSingleObject(_ReadOverlapped.hEvent,dwWaitTime);
//结束异步I/O
if(!
:
:
GetOverlappedResult(_hCommHandle,&_ReadOverlapped,&uReadLength,false))
{
if(:
:
GetLastError()!
=ERROR_IO_INCOMPLETE)
uReadLength=0;
}
}
else
uReadLength=0;
}
returnuReadLength;
}
//读取串口dwBufferLength-1个字符到szBuffer返回ANSIC模式字符串指针适合一般字符通讯
char*ReadString(char*szBuffer,DWORDdwBufferLength,DWORDdwWaitTime=20)
{
unsignedlonguReadLength=Read(szBuffer,dwBufferLength-1,dwWaitTime);
szBuffer[uReadLength]='\0';
returnszBuffer;
}
//写串口可写任意数据"abcd"or"\x0\x1\x2"
DWORDWrite(LPVOIDBuffer,DWORDdwBufferLength)
{
if(!
IsOpen())
return0;
DWORDdwError;
if(:
:
ClearCommError(_hCommHandle,&dwError,NULL)&&dwError>0)
:
:
PurgeComm(_hCommHandle,PURGE_TXABORT|PURGE_TXCLEAR);
unsignedlonguWriteLength=0;
if(!
:
:
WriteFile(_hCommHandle,Buffer,dwBufferLength,&uWriteLength,&_WriteOverlapped))
if(:
:
GetLastError()!
=ERROR_IO_PENDING)
uWriteLength=0;
returnuWriteLength;
}
//写串口写ANSIC模式字符串指针
DWORDWrite(constchar*szBuffer)
{
assert(szBuffer);
returnWrite((void*)szBuffer,strlen(szBuffer));
}
//读串口同步应用
DWORDReadSync(LPVOIDBuffer,DWORDdwBufferLength)
{
if(!
IsOpen())
return0;
DWORDdwError;
if(:
:
ClearCommError(_hCommHandle,&dwError,NULL)&&dwError>0)
{
:
:
PurgeComm(_hCommHandle,PURGE_RXABORT|PURGE_RXCLEAR);
return0;
}
DWORDuReadLength=0;
:
:
ReadFile(_hCommHandle,Buffer,dwBufferLength,&uReadLength,NULL);
returnuReadLength;
}
//写串口同步应用
DWORDWriteSync(LPVOIDBuffer,DWORDdwBufferLength)
{
if(!
IsOpen())
return0;
DWORDdwError;
if(:
:
ClearCommError(_hCommHandle,&dwError,NULL)&&dwError>0)
:
:
PurgeComm(_hCommHandle,PURGE_TXABORT|PURGE_TXCLEAR);
unsignedlonguWriteLength=0;
:
:
WriteFile(_hCommHandle,Buffer,dwBufferLength,&uWriteLength,NULL);
returnuWriteLength;
}
//写串口szBuffer可以输出格式字符串包含缓冲区长度
DWORDWrite(char*szBuffer,DWORDdwBufferLength,char*szFormat,...)
{
if(!
IsOpen())
return0;
va_listva;
va_start(va,szFormat);
_vsnprintf(szBuffer,dwBufferLength,szFormat,va);
va_end(va);
returnWrite(szBuffer);
}
//写串口szBuffer可以输出格式字符串不检查缓冲区长度小心溢出
DWORDWrite(char*szBuffer,char*szFormat,...)
{
if(!
IsOpen())
return0;
va_listva;
va_start(va,szFormat);
vsprintf(szBuffer,szFormat,va);
va_end(va);
returnWrite(szBuffer);
}
//关闭串口同时也关闭关联线程
virtualvoidClose()
{
if(IsOpen())
{
PurgeComm(_hCommHandle,PURGE_TXABORT|PURGE_TXCLEAR);
EndThread();
:
:
CloseHandle(_hCommHandle);
_hCommHandle=INVALID_HANDLE_VALUE;
}
}
//DTR电平控制
boolSetDTR(boolOnOrOff)
{
returnIsOpen()?
EscapeCommFunction(_hCommHandle,OnOrOff?
SETDTR:
CLRDTR):
false;
}
//RTS电平控制
boolSetRTS(boolOnOrOff)
{
returnIsOpen()?
EscapeCommFunction(_hCommHandle,OnOrOff?
SETRTS:
CLRRTS):
false;
}
//
boolSetBreak(boolOnOrOff)
{
returnIsOpen()?
EscapeCommFunction(_hCommHandle,OnOrOff?
SETBREAK:
CLRBREAK):
false;
}
//辅助线程控制建监视线程
boolBeginThread()
{
if(!
IsThreadRunning())
{
_fRunFlag=true;
_hThreadHandle=NULL;
DWORDid;
_hThreadHandle=:
:
CreateThread(NULL,0,CommThreadProc,this,0,&id);
return(_hThreadHandle!
=NULL);
}
returnfalse;
}
//暂停监视线程
inlineboolSuspendThread()
{
returnIsThreadRunning()?
:
:
SuspendThread(_hThreadHandle)!
=0xFFFFFFFF:
false;
}
//恢复监视线程
inlineboolResumeThread()
{
returnIsThreadRunning()?
:
:
ResumeThread(_hThreadHandle)!
=0xFFFFFFFF:
false;
}
//终止线程
boolEndThread(DWORDdwWaitTime=100)
{
if(IsThreadRunning())
{
_fRunFlag=false;
:
:
SetCommMask(_hCommHandle,0);
:
:
SetEvent(_WaitOverlapped.hEvent);
if(:
:
WaitForSingleObject(_hThreadHandle,dwWaitTime)!
=WAIT_OBJECT_0)
if(!
:
:
TerminateThread(_hThreadHandle,0
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第三 串口 编程
![提示](https://static.bdocx.com/images/bang_tan.gif)