這是我在一個後臺系統摘抄出來的,在此基礎上完成了一個獨立的PPI讀寫程序(非DLL或控件方式)
//*************************************************************************
//**模 塊 名:YFCOM.cpp
//**說 明:YFSoft 版權所有2005 - 2006(C)
//**創 建 人:葉帆
//**日 期:2006年4月4日
//**修 改 人:
//**日 期:
//**描 述:串口操作
//**版 本:V1.0
//*************************************************************************
#include "stdafx.h"
#include "yfcom.h"
//串口句柄
HANDLE m_COM_Handle;
//兩個信號全局變量(串口操作用)
OVERLAPPED m_OverlappedRead, m_OverlappedWrite;
//*************************************************************************
//函 數 名:OpenCom
//輸 入:long lngPort, 串口號
// char *cfgMessage, 配置信息,形如"9600,e,8,1"
// long lngInSize, 接收緩衝區大小
// long lngOutSize 發送緩衝區大小
//輸 出:long
//功能描述:打開串口
//全局變量:
//調用模塊:
//作 者:葉帆
//日 期:2006年4月4日
//修 改 人:
//日 期:
//版 本:
//*************************************************************************
long OpenCom(long lngPort,char *cfgMessage,long lngInSize,long lngOutSize)
{
try
{
char szMsg[255];
DCB dcb;
//打開端口
if (lngPort>9)
sprintf( szMsg, "////.//COM%d", lngPort );
else
sprintf( szMsg, "COM%d", lngPort );
//用異步方式讀寫串口
m_COM_Handle = CreateFile(szMsg, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED , NULL );
if( m_COM_Handle == NULL ) return( 2 );
//清空異步讀寫參數
memset(&(m_OverlappedRead), 0, sizeof (OVERLAPPED));
memset(&(m_OverlappedWrite), 0, sizeof (OVERLAPPED));
//設置dcb塊
dcb.DCBlength = sizeof( DCB ); //長度
GetCommState(m_COM_Handle , &dcb );
//波特率,奇偶校驗,數據位,停止位 如:9600,n,8,1
sprintf(szMsg,"COM%d:%s", lngPort,cfgMessage);
BuildCommDCB(szMsg,&dcb);
//------------------------------
dcb.fBinary=TRUE; //二進制方式
dcb.fOutxCtsFlow=FALSE; //不用CTS檢測發送流控制
dcb.fOutxDsrFlow=FALSE; //不用DSR檢測發送流控制
dcb.fDtrControl=DTR_CONTROL_DISABLE; //禁止DTR流量控制
dcb.fDsrSensitivity=FALSE; //對DTR信號線不敏感
dcb.fTXContinueOnXoff=TRUE; //檢測接收緩衝區
dcb.fOutX=FALSE; //不做發送字符控制
dcb.fInX =FALSE; //不做接收控制
dcb.fErrorChar=FALSE; //是否用指定字符替換校驗錯的字符
dcb.fNull=FALSE; //保留NULL字符
dcb.fRtsControl=RTS_CONTROL_ENABLE; //允許RTS流量控制
dcb.fAbortOnError=FALSE; //發送錯誤後,繼續進行下面的讀寫操作
dcb.fDummy2=0; //保留
dcb.wReserved=0; //沒有使用,必須爲0
dcb.XonLim=0; //指定在XOFF字符發送之前接收到緩衝區中可允許的最小字節數
dcb.XoffLim=0; //指定在XOFF字符發送之前緩衝區中可允許的最小可用字節數
dcb.XonChar=0; //發送和接收的XON字符
dcb.XoffChar=0; //發送和接收的XOFF字符
dcb.ErrorChar=0; //代替接收到奇偶校驗錯誤的字符
dcb.EofChar=0; //用來表示數據的結束
dcb.EvtChar=0; //事件字符,接收到此字符時,會產生一個事件
dcb.wReserved1=0; //沒有使用
//dcb.BaudRate =9600; //波特率
//dcb.Parity=0; //奇偶校驗
//dcb.ByteSize=8; //數據位
//dcb.StopBits=0; //停止位
//------------------------------
if(dcb.Parity==0 ) // 0-4=None,Odd,Even,Mark,Space
{
dcb.fParity=FALSE; //奇偶校驗無效
}
else
{
dcb.fParity=TRUE; //奇偶校驗有效
}
sprintf(szMsg,"COM%d:%d,%d,%d,%d (InSize:%ld,OutSize:%ld)", lngPort,dcb.BaudRate,dcb.Parity,dcb.ByteSize,dcb.StopBits,lngInSize,lngOutSize);
//讀寫超時設置
COMMTIMEOUTS CommTimeOuts;
//西門子參數
CommTimeOuts.ReadIntervalTimeout =0; //字符允許間隔ms 該參數如果爲最大值,會使readfile命令立即返回
CommTimeOuts.ReadTotalTimeoutMultiplier =0; //總的超時時間(對單個字節)
CommTimeOuts.ReadTotalTimeoutConstant = 2500; //多餘的超時時間ms
CommTimeOuts.WriteTotalTimeoutMultiplier =0; //總的超時時間(對單個字節)
CommTimeOuts.WriteTotalTimeoutConstant = 2500; //多餘的超時時間
SetCommTimeouts( m_COM_Handle, &CommTimeOuts );
//獲取信號句柄
m_OverlappedRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
m_OverlappedWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if( !SetCommState( m_COM_Handle, &dcb ) || //判斷設置參數是否成功
!SetupComm( m_COM_Handle, lngInSize, lngOutSize ) || //設置輸入和輸出緩衝區是否成功
m_OverlappedRead.hEvent==NULL ||
m_OverlappedWrite.hEvent==NULL)
{
DWORD dwError = GetLastError(); //獲取最後的錯誤信息
if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
CloseHandle( m_COM_Handle );
m_COM_Handle=NULL;
return dwError;
}
return( 0 );
}
catch(...)
{
return -1;
}
}
//*************************************************************************
//函 數 名:CloseCom
//輸 入:
//輸 出:long
//功能描述:關閉串口
//全局變量:
//調用模塊:
//作 者:葉帆
//日 期:2006年4月4日
//修 改 人:
//日 期:
//版 本:
//*************************************************************************
long CloseCom()
{
try
{
if(m_COM_Handle == NULL ) return( 1 );
SetCommMask(m_COM_Handle ,NULL);
SetEvent(m_OverlappedRead.hEvent);
SetEvent(m_OverlappedWrite.hEvent);
if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
if (CloseHandle( m_COM_Handle )==FALSE)return (2);
m_COM_Handle = NULL;
}
catch(...)
{
return (3);
}
return( 0 );
}
//*************************************************************************
//函 數 名:SendData
//輸 入:BYTE *bytBuffer, 數據
// long lngSize 個數
//輸 出:long
//功能描述:發送數據
//全局變量:
//調用模塊:
//作 者:葉帆
//日 期:2006年4月4日
//修 改 人:
//日 期:
//版 本:
//*************************************************************************
long SendData(BYTE *bytBuffer, long lngSize )
{
try
{
if( m_COM_Handle == NULL ) return( -1 );
DWORD dwBytesWritten=lngSize;
BOOL bWriteStat;
COMSTAT ComStat;
DWORD dwErrorFlags;
ClearCommError(m_COM_Handle,&dwErrorFlags,&ComStat);
bWriteStat=WriteFile(m_COM_Handle, bytBuffer, lngSize, &dwBytesWritten, &(m_OverlappedWrite));
if(!bWriteStat)
{
if(GetLastError()==ERROR_IO_PENDING)
{
GetOverlappedResult(m_COM_Handle,&(m_OverlappedWrite),&dwBytesWritten,TRUE); //等待直到發送完畢
}
else
{
dwBytesWritten=0;
}
}
return (long)dwBytesWritten;
}
catch(...)
{
return -1;
}
}
//*************************************************************************
//函 數 名:AcceptData
//輸 入:BYTE *bytBuffer, 數據
// long lngSize 個數
//輸 出:long
//功能描述:讀取數據
//全局變量:
//調用模塊:
//作 者:葉帆
//日 期:2006年4月4日
//修 改 人:
//日 期:
//版 本:
//*************************************************************************
long AcceptData(BYTE *bytBuffer, long lngSize )
{
try
{
if( m_COM_Handle == NULL ) return( -1 );
DWORD lngBytesRead=lngSize;
BOOL fReadStat;
DWORD dwRes=0;
//讀數據
fReadStat=ReadFile(m_COM_Handle,bytBuffer,lngSize,&lngBytesRead,&(m_OverlappedRead));
//Sleep(1);
if( !fReadStat )
{
if( GetLastError() == ERROR_IO_PENDING ) //重疊 I/O 操作在進行中
{
dwRes=WaitForSingleObject(m_OverlappedRead.hEvent,1000); //等待,直到超時
switch(dwRes)
{
case WAIT_OBJECT_0: //讀完成
if(GetOverlappedResult(m_COM_Handle,&(m_OverlappedRead),&lngBytesRead,FALSE)==0)
{
//錯誤
return -2;
}
break;
case WAIT_TIMEOUT: //超時
return -1;
break;
default: //WaitForSingleObject 錯誤
break;
}
}
}
return lngBytesRead;
}
catch(...)
{
return -1;
}
}
//*************************************************************************
//函 數 名:ClearAcceptBuffer
//輸 入:
//輸 出:long
//功能描述:清除接收緩衝區
//全局變量:
//調用模塊:
//作 者:葉帆
//日 期:2006年4月4日
//修 改 人:
//日 期:
//版 本:
//*************************************************************************
long ClearAcceptBuffer()
{
try
{
if(m_COM_Handle == NULL ) return( -1 );
PurgeComm(m_COM_Handle,PURGE_RXABORT | PURGE_RXCLEAR); //
}
catch(...)
{
return(1);
}
return(0);
}
//*************************************************************************
//函 數 名:ClearSendBuffer
//輸 入:
//輸 出:long
//功能描述:清除發送緩衝區
//全局變量:
//調用模塊:
//作 者:葉帆
//日 期:2006年4月4日
//修 改 人:
//日 期:
//版 本:
//*************************************************************************
long ClearSendBuffer()
{
try
{
if(m_COM_Handle == NULL ) return( -1 );
PurgeComm(m_COM_Handle,PURGE_TXABORT | PURGE_TXCLEAR); //
}
catch(...)
{
return (1);
}
return(0);
}