VC++串口通讯.docx

上传人:b****2 文档编号:1630715 上传时间:2023-05-01 格式:DOCX 页数:10 大小:17.63KB
下载 相关 举报
VC++串口通讯.docx_第1页
第1页 / 共10页
VC++串口通讯.docx_第2页
第2页 / 共10页
VC++串口通讯.docx_第3页
第3页 / 共10页
VC++串口通讯.docx_第4页
第4页 / 共10页
VC++串口通讯.docx_第5页
第5页 / 共10页
VC++串口通讯.docx_第6页
第6页 / 共10页
VC++串口通讯.docx_第7页
第7页 / 共10页
VC++串口通讯.docx_第8页
第8页 / 共10页
VC++串口通讯.docx_第9页
第9页 / 共10页
VC++串口通讯.docx_第10页
第10页 / 共10页
亲,该文档总共10页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

VC++串口通讯.docx

《VC++串口通讯.docx》由会员分享,可在线阅读,更多相关《VC++串口通讯.docx(10页珍藏版)》请在冰点文库上搜索。

VC++串口通讯.docx

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

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 工作范文 > 行政公文

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2