VC++串口通讯.docx
- 文档编号:12277603
- 上传时间:2023-04-17
- 格式:DOCX
- 页数:10
- 大小:17.63KB
VC++串口通讯.docx
《VC++串口通讯.docx》由会员分享,可在线阅读,更多相关《VC++串口通讯.docx(10页珍藏版)》请在冰豆网上搜索。
VC++串口通讯
VC++的串口通讯
代翔
在VC++中有两种方法可以进行串口通讯。
一种是利用Microsoft公司提供的ActiveX
控件MicrosoftCommunicationsControl。
另一种是直接用VC++访问串口。
下面将简述
这两种方法。
一、MicrosoftCommunicationsControl
Microsoft公司在Windows中提供了一个串口通讯控件,用它,我们可以很简单
的利用串口进行通讯。
在使用它之前,应将控件加在应用程序的对话框上。
然后再用
ClassWizard生成相应的对象。
现在我们可以使用它了。
该控件有很多自己的属性,你可以通过它的属性窗口来设置,也可以用程序设置
。
我推荐用程序设置,这样更灵活。
SetCommPort:
指定使用的串口。
GetCommPort:
得到当前使用的串口。
SetSettings:
指定串口的参数。
一般设为默认参数"9600,N,8,1"。
这样方便
与其他串口进行通讯。
GetSettings:
取得串口参数。
SetPortOpen:
打开或关闭串口,当一个程序打开串口时,另外的程序将无法使
用该串口。
GetPortOpen:
取得串口状态。
GetInBufferCount:
输入缓冲区中接受到的字符数。
SetInPutLen:
一次读取输入缓冲区的字符数。
设置为0时,程序将读取缓冲区的
全部字符。
GetInPut:
读取输入缓冲区。
GetOutBufferCount:
输出缓冲区中待发送的字符数。
SetOutPut:
写入输出缓冲区。
一般而言,使用上述函数和属性就可以进行串口通讯了。
以下是一个范例。
#defineMESSAGELENGTH100
classCMyDialog:
publicCDialog
{
protected:
VARIANTInBuffer;
VARIANTOutBuffer;
CMSCommm_Com;
public:
......
}
BOOLCMyDiaLog:
:
OnInitDialog()
{
CDialog:
:
OnInitDialog();
m_Com.SetCommPort
(1);
if(!
m_Com.GetPortOpen()){
m_Com.SetSettings("57600,N,8,1");
m_Com.SetPortOpen(true);
m_Com.SetInBufferCount(0);
SetTimer(1,10,NULL);
InBuffer.bstrVal=newunsignedshort[MESSAGELENGTH];
OutBuffer.bstrVal=newunsignedshort[MESSAGELENGTH];
OutBuffer.vt=VT_BSTR;
}
returntrue;
}
voidCMyDiaLog:
:
OnTimer(UINTnIDEvent)
{
if(m_Com.GetInBufferCount()>=MESSAGELENGTH){
InBuffer=m_Com.GetInput();
//handletheInBuffer.
//FilltheOutBuffer.
m_Com.SetOutput(OutBuffer);
}
CDialog:
:
OnTimer(nIDEvent);
}
用该控件传输的数据是UNICODE格式。
关于UNICODE和ANSI的关系和转换请参
看MSDN。
关于该控件的其他详细资料请查看MSDN关于COMMCONTROL部分。
二、直接用VC++访问串口。
在VC++中,串口和磁盘文件可以统一的方式来简单读写。
这两者几乎没有什么不
同,只是在Windows9X下磁盘文件只能做同步访问,而串口只能做异步访问。
CreateFile:
用指定的方式打开指定的串口。
通常的方式为
m_hCom=CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,NULL,
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,NULL);
m_hCom为文件句柄。
GENERIC_READ|GENERIC_WRITE指定可以对串口进行读
写操作。
第三个参数0表示串口为独占打开。
OPEN_EXISTING表示当指定串口不存在
时,程序将返回失败。
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED则表
示文件属性。
当打开串口时,必须指定FILE_FLAG_OVERLAPPED,它表示文件或设
备不会维护访问指针,则在读写时,必须使用OVERLAPPED结构指定访问的文件偏移
量。
ReadFile:
读取串口数据。
WriteFile:
向串口写数据。
CloseHandle:
关闭串口。
COMMTIMEOUTS:
COMMTIMEOUTS主要用于串口超时参数设置。
COMMTIMEOUTS结构如下:
typedefstruct_COMMTIMEOUTS{
DwordReadIntervalTimeout;
DwordReadTotalTimeoutMultiplier;
DwordReadTotalTimeoutConstant;
DwordWriteTotalTimeoutMultiplier;
DwordWriteTotalTimeoutConstant;
}COMMTIMEOUTS,*LPCOMMTIMEOUTS;
ReadIntervalTimeout:
两字符之间最大的延时,当读取串口数据时,一旦两个字符
传输的时间差超过该时间,读取函数将返回现有的数据。
设置为0表示该参数不起作用
。
ReadTotalTimeoutMultiplier:
读取每字符间的超时。
ReadTotalTimeoutConstant:
一次读取串口数据的固定超时。
所以在一次读取串口
的操作中,其超时为ReadTotalTimeoutMultiplier乘以读取的字节数再加上
ReadTotalTimeoutConstant。
将ReadIntervalTimeout设置为MAXDword,并将
ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant设置为0,表示读取操作将立即
返回存放在输入缓冲区的字符。
WriteTotalTimeoutMultiplier:
写入每字符间的超时。
WriteTotalTimeoutConstant:
一次写入串口数据的固定超时。
所以在一次写入串口
的操作中,其超时为WriteTotalTimeoutMultiplier乘以写入的字节数再加上
WriteTotalTimeoutConstant。
SetCommTimeouts函数可以设置某设备句柄的超时参数,要得到某设备句柄的超
时参数可以用GetCommTimeouts函数。
DCB:
DCB结构主要用于串口参数设置。
该结构太庞大,这里就不一一讲述了,
有兴趣者可查看MSDN关于DCB的描述。
其中下面两个是比较重要的属性。
BaudRate:
串口的通讯速度。
一般设置为9600。
ByteSize:
字节位数。
一般设置为8。
DCB结构可以用SetCommState函数来设置,并可以用GetCommState来得到现有串
口的属性。
SetupComm:
设置串口输入、输出缓冲区。
OVERLAPPED:
保存串口异步通讯的信息。
具体结构如下:
typedefstruct_OVERLAPPED{
DwordInternal;
DwordInternalHigh;
DwordOffset;
DwordOffsetHigh;
HANDLEhEvent;
}OVERLAPPED;
Internal,InternalHigh是保留给系统使用的,用户不需要设置。
Offset,OffsetHigh是读写串口的偏移量,一般设置OffsetHigh为NULL,可以支持
2GB数据。
hEvent读写事件,因为串口是异步通讯,操作可能被其他进程堵塞,程序可以通
过检查该时间来得知是否读写完毕。
事件将在读写完成后,自动设置为有效。
通过以上这些函数和结构,我们就可以通过串口进行通讯了,现在我们具体看下
面的实例:
BOOLCSerial:
:
Open(intnPort,intnBaud)
{
if(m_bOpened)return(TRUE);
charszPort[15];
DCBdcb;
wsprintf(szPort,"COM%d",nPort);
m_hComDev=CreateFile(szPort,GENERIC_READ|GENERIC_WRITE,0,NULL,
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,NULL);
if(m_hComDev==NULL)return(FALSE);
memset(&m_OverlappedRead,0,sizeof(OVERLAPPED));
memset(&m_OverlappedWrite,0,sizeof(OVERLAPPED));
COMMTIMEOUTSCommTimeOuts;
CommTimeOuts.ReadIntervalTimeout=0xFFFFFFFF;
CommTimeOuts.ReadTotalTimeoutMultiplier=0;
CommTimeOuts.ReadTotalTimeoutConstant=0;
CommTimeOuts.WriteTotalTimeoutMultiplier=0;
CommTimeOuts.WriteTotalTimeoutConstant=5000;
SetCommTimeouts(m_hComDev,&CommTimeOuts);
m_OverlappedRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
m_OverlappedWrite.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
dcb.DCBlength=sizeof(DCB);
GetCommState(m_hComDev,&dcb);
dcb.BaudRate=nBaud;
dcb.ByteSize=8;
if(!
SetCommState(m_hComDev,&dcb)||
!
SetupComm(m_hComDev,10000,10000)||
m_OverlappedRead.hEvent==NULL||
m_OverlappedWrite.hEvent==NULL){
DworddwError=GetLastError();
if(m_OverlappedRead.hEvent!
=NULL)CloseHandle(m_OverlappedRead.hEvent);
if(m_OverlappedWrite.hEvent!
=NULL)CloseHandle(m_OverlappedWrite.hEvent);
CloseHandle(m_hComDev);
returnFALSE;
}
m_bOpened=TRUE;
returnm_bOpened;
}
intCSerial:
:
InBufferCount(void)
{
if(!
m_bOpened||m_hComDev==NULL)return(0);
DworddwErrorFlags;
COMSTATComStat;
ClearCommError(m_hIDComDev,&dwErrorFlags,&ComStat);
return(int)ComStat.cbInQue;
}
DWORDCSerial:
:
ReadData(void*buffer,DworddwBytesRead)
{
if(!
m_bOpened||m_hComDev==NULL)return0;
BOOLbReadStatus;
DworddwErrorFlags;
COMSTATComStat;
ClearCommError(m_hComDev,&dwErrorFlags,&ComStat);
if(!
ComStat.cbInQue)return0;
dwBytesRead=min(dwBytesRead,(Dword)ComStat.cbInQue);
bReadStatus=ReadFile(m_hComDev,buffer,dwBytesRead,&dwBytesRead,
&m_OverlappedRead);
if(!
bReadStatus){
if(GetLastError()==ERROR_IO_PENDING){
WaitForSingleObject(m_OverlappedRead.hEvent,2000);
returndwBytesRead;
}
return0;
}
returndwBytesRead;
}
DWORDCSerial:
:
SendData(constchar*buffer,DworddwBytesWritten)
{
if(!
m_bOpened||m_hComDev==NULL)return(0);
BOOLbWriteStat;
bWriteStat=WriteFile(m_hComDev,buffer,dwBytesWritten,&dwBytesWritten,
&m_OverlappedWrite);
if(!
bWriteStat){
if(GetLastError()==ERROR_IO_PENDING){
WaitForSingleObject(m_OverlappedWrite.hEvent,1000);
returndwBytesWritten;
}
return0;
}
returndwBytesWritten;
}
上述函数基本实现串口的打开,读写操作。
本文章略去该串口类的说明和关闭函
数。
读者应该能将这些内容写完。
接下来,你就可以在你的程序中调用该串口类了。
关于本文有任何疑问,请与作者联系。
本文参考文献:
MSDN1999,MicrosoftCorp
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- VC 串口 通讯