Windows CE下的串口通讯实例.docx
《Windows CE下的串口通讯实例.docx》由会员分享,可在线阅读,更多相关《Windows CE下的串口通讯实例.docx(8页珍藏版)》请在冰豆网上搜索。
WindowsCE下的串口通讯实例
WindowsCE下的串口通讯实例
发布日期:
2009-01-1401:
37:
13作者:
admin来源:
浏览次数:
792
串行通讯是目前计算机、通信和控制领域最基本的通信方式。
经常有人提问该到哪找串口通讯例子,其实这个问题一般的回答是给你提供一个PocketPC2002的SDK例子程序。
但到底SDK的程序和MFC的结构有很大的不同,对于想用MFC编写通信程序的人来说也不是很便利。
另一方面,由于WindowsCE是一个基于Unicode的操作系统,并且WindowsCE不支持Windows下常用的串行通信重叠I/O方式(OVERLAPPED),因此编写WindowsCE下的串口通讯类有一些与桌面Windows不同的地方。
该程序是基于“主动发送请求,被动接收响应”的假设,因此只设置了一个接收数据的线程。
源代码如下:
头文件Serial.h
//Serial.h:
interfacefortheCSerialclass.
//
//////////////////////////////////////////////////////////////////////
#if!
defined(AFX_SERIAL_H__59575586_AAA9_4FEF_B2A7_E089553698EF__INCLUDED_)
#defineAFX_SERIAL_H__59575586_AAA9_4FEF_B2A7_E089553698EF__INCLUDED_
#if_MSC_VER>1000
#pragmaonce
#endif//_MSC_VER>1000
DWORDWINAPIReadPortThread(LPVOIDlpvoid);//读数据线程
classCSerial
{
public:
BOOLInitCommTimeouts();//设置超时参数
BOOLInitDCB();//配置串口
BOOLm_bConnected;
BOOLClosePort(HANDLEhCommPort);//关闭串口
DWORDWritePort(TCHAR*buf,DWORDdwBytesToWrite);//写数据
BOOLOpenPort(LPTSTRlpszPortName);//打开串口
CSerial();
HANDLEhReadThread;
virtual~CSerial();
};
#endif//!
defined(AFX_SERIAL_H__59575586_AAA9_4FEF_B2A7_E089553698EF__INCLUDED_)
源文件:
Serial.cpp
//Serial.cpp:
implementationoftheCSerialclass.
//
//////////////////////////////////////////////////////////////////////
#include"stdafx.h"
#include"Serial.h"
#ifdef_DEBUG
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#definenewDEBUG_NEW
#endif
HANDLEhPort;
CStringstrInChar;
//////////////////////////////////////////////////////////////////////
//Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSerial:
:
CSerial()
{
}
CSerial:
:
~CSerial()
{
if(hPort!
=INVALID_HANDLE_VALUE)
ClosePort(hPort);
}
BOOLCSerial:
:
OpenPort(LPTSTRlpszPortName)
{
DWORDdwError,
dwThreadID;
if(hPort)
{
returnFALSE;
}
//打开串口
hPort=CreateFile(lpszPortName,GENERIC_READ|GENERIC_WRITE,
0,NULL,OPEN_EXISTING,0,NULL);
//如果打开端口出错,返回FALSE
if(hPort==INVALID_HANDLE_VALUE)
{
//不能打开端口
CStringstrError;
strError.Format(_T("Unabletoopen%s,ErrorNo.=%d"),
lpszPortName,GetLastError());
MessageBox(NULL,strError, TEXT("Error"),MB_OK);
returnFALSE;
}
//指定端口监测的事件集
SetCommMask(hPort,EV_RXCHAR);
//分配设备缓冲区
SetupComm(hPort,512,512);
//初始化缓冲区中的信息
PurgeComm(hPort,PURGE_TXCLEAR|PURGE_RXCLEAR);
//配置串行端口
if(!
InitDCB())
returnFALSE;
//设置端口超时值
if(!
InitCommTimeouts())
returnFALSE;
//设置端口上指定信号的状态
//SETDTR:
发送DTR(data-terminal-ready)信号
//SETRTS:
发送RTS(request-to-send)信号
EscapeCommFunction(hPort,SETDTR);
EscapeCommFunction(hPort,SETRTS);
//创建一个从串口读取数据的线程
if(hReadThread=CreateThread(NULL,0,ReadPortThread,0,0,
&dwThreadID))
{
}
else
{
//不能创建线程
MessageBox(NULL,TEXT("Unabletocreatethereadthread"),
TEXT("Error"),MB_OK);
dwError=GetLastError();
returnFALSE;
}
m_bConnected=TRUE;
returnTRUE;
}
DWORDCSerial:
:
WritePort(TCHAR*buf,DWORDdwCharToWrite)
{
BOOLfWriteState;
DWORDdwBytesWritten;
//写入数据
fWriteState=WriteFile(hPort,buf,dwCharToWrite*sizeof(TCHAR),&dwBytesWritten,NULL);
if(!
fWriteState)
{
//不能写数据
MessageBox(NULL,TEXT("Can'tWriteStringtoComm"),TEXT("Error"),MB_OK);
dwBytesWritten=0;
}
returndwBytesWritten;
}
DWORDWINAPIReadPortThread(LPVOIDlpvoid)
{
BOOLfReadState;
DWORDdwCommModemStatus;
DWORDdwLength;
COMSTATComStat;
DWORDdwErrorFlags;
while(hPort!
=INVALID_HANDLE_VALUE)
{
//等待串口的事件发生
WaitCommEvent(hPort,&dwCommModemStatus,0);
if(dwCommModemStatus&EV_RXCHAR)
{
ClearCommError(hPort,&dwErrorFlags,&ComStat);
//cbInQue返回在串行驱动程序输入队列中的字符数
dwLength=ComStat.cbInQue;
if(dwLength>0)
{
//从串口读取数据
TCHAR*buf=newTCHAR[256];
fReadState=ReadFile(hPort,buf,dwLength,&dwLength,NULL);
if(!
fReadState)
{
//不能从串口读取数据
MessageBox(NULL,TEXT("Errorinreadfromserialport"),TEXT("ReadError"),MB_OK);
}
else
{
//把数据赋值给全局变量
strInChar=buf;
}
delete[]buf;
}
}
GetCommModemStatus(hPort,&dwCommModemStatus);
}
return0;
}
BOOLCSerial:
:
ClosePort(HANDLEhCommPort)
{
if(hCommPort!
=INVALID_HANDLE_VALUE)
{
//设置连接属性为FALSE
m_bConnected=FALSE;
//结束线程中WaitCommEvent的等待
SetCommMask(hPort,0);
//阻塞至线程停止
if(hReadThread)
{
TerminateThread(hReadThread,0);
CloseHandle(hReadThread);
}
//清除端口上指定信号的状态
EscapeCommFunction(hPort,CLRDTR);
EscapeCommFunction(hPort,CLRRTS);
//清除驱动程序内部的发送和接收队列
PurgeComm(hPort,PURGE_TXCLEAR|PURGE_RXCLEAR);
//关闭串口
CloseHandle(hCommPort);
hCommPort=INVALID_HANDLE_VALUE;
returnTRUE;
}
else
{
returnTRUE;
}
}
BOOLCSerial:
:
InitDCB()
{
DCBPortDCB;
DWORDdwError;
PortDCB.DCBlength=sizeof(DCB);
//得到端口的默认设置信息
GetCommState(hPort,&PortDCB);
//改变DCB结构设置
PortDCB.BaudRate=19200; //波特率
PortDCB.fBinary=TRUE; //Win32不支持非二进制串行传输模式,必须为TRUE
PortDCB.fParity=TRUE; //启用奇偶校验
PortDCB.fOutxCtsFlow=TRUE; //串行端口的输出由CTS线控制
PortDCB.fOutxDsrFlow=FALSE; //关闭串行端口的DSR流控制
PortDCB.fDtrControl=DTR_CONTROL_ENABLE; //启用DTR线
PortDCB.fDsrSensitivity=FALSE; //如果设为TRUE将忽略任何输入的字节,除非DSR线被启用
//PortDCB.fTXContinueOnXoff=TRUE; //当为TRUE时,如果接收缓冲区已满且驱动程序已传送XOFF字符,将使驱动程序停止传输字符
PortDCB.fTXContinueOnXoff=FALSE;
PortDCB.fOutX=FALSE; //设为TRUE指定XON/XOFF控制被用于控制串行输出
PortDCB.fInX=FALSE; //设为TRUE指定XON/XOFF控制被用于控制串行输入
PortDCB.fErrorChar=FALSE; //WINCE串行驱动程序的默认执行将忽略这个字段
PortDCB.fNull=FALSE; //设为TRUE将使串行驱动程序忽略收到的空字节
PortDCB.fRtsControl=RTS_CONTROL_ENABLE; //启用RTS线
PortDCB.fAbortOnError=FALSE; //WINCE串行驱动程序的默认执行将忽略这个字段
PortDCB.ByteSize=8; //每字节的位数
PortDCB.Parity=NOPARITY; //无奇偶校验
PortDCB.StopBits=ONESTOPBIT; //每字节一位停止位
//根据DCB结构配置端口
if(!
SetCommState(hPort,&PortDCB))
{
//不能配置串行端口
MessageBox(NULL,TEXT("Unabletoconfiguretheserialport"),
TEXT("Error"),MB_OK);
dwError=GetLastError();
returnFALSE;
}
returnTRUE;
}
BOOLCSerial:
:
InitCommTimeouts()
{
COMMTIMEOUTSCommTimeouts;
DWORDdwError;
//得到超时参数
GetCommTimeouts(hPort,&CommTimeouts);
//改变COMMTIMEOUTS结构设置
CommTimeouts.ReadIntervalTimeout=MAXDWORD;
CommTimeouts.ReadTotalTimeoutMultiplier=0;
CommTimeouts.ReadTotalTimeoutConstant=0;
CommTimeouts.WriteTotalTimeoutMultiplier=10;
CommTimeouts.WriteTotalTimeoutConstant=1000;
//设置端口超时值
if(!
SetCommTimeouts(hPort,&CommTimeouts))
{
//不能设置超时值
MessageBox(NULL,TEXT("Unabletosetthetime-outparameters"),
TEXT("Error"),MB_OK);
dwError=GetLastError();
returnFALSE;
}
returnTRUE;
}
以上类代码在eMbeddedVisualC++4.0和基于ARM9的三星S3C2410开发板(运行WindowsCE.NET4.1)上测试通过。