📄 comport.cpp
字号:
// ComPort.cpp: implementation of the CComPort class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "RegionComm.h"
#include "ComPort.h"
#include "Communication.h"
#include "RegionSocket.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
extern bool bgpsOK;
extern long igps;
extern CString sgps;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CComPort::CComPort(CCommunication *pComm)
{
m_bPortOpen=FALSE;
m_ComPort=0;
m_ComBitRate=9600;
m_pOwner = pComm;
TimeOutCount=15;
IsConnected=FALSE;
nTimeCount=-1;
}
CComPort::~CComPort()
{
SetCommMask( m_hcom, 0 ) ;
if (m_hcom != INVALID_HANDLE_VALUE)
::CloseHandle(m_hcom);
::CloseHandle(m_hProcessEvent);
CloseHandle(m_osRead.hEvent );
CloseHandle(m_osWrite.hEvent );
CloseHandle(m_osWait.hEvent);
//Close();
}
//打开串口
BOOL CComPort::Open()
{
// COMMTIMEOUTS CommTimeOuts ;
CString portstr;
DCB dcb ;
memset(&m_osRead, 0, sizeof(OVERLAPPED));
if( NULL==(m_osRead.hEvent = CreateEvent( NULL, // no security
TRUE, // explicit reset req
FALSE, // initial event reset
NULL ) )) // no name
return(FALSE);
memset(&m_osWrite, 0, sizeof(OVERLAPPED));
if( NULL==(m_osWrite.hEvent = CreateEvent( NULL, // no security
TRUE, // explicit reset req
FALSE, // initial event reset
NULL ))) //no name
return(FALSE);
memset(&m_osWait, 0, sizeof(OVERLAPPED));
if(NULL==(m_osWait.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
return(FALSE);
if(NULL==(m_hProcessEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL)))
return(FALSE);
if(m_ComPort==0)
return(FALSE);
if(m_bPortOpen)
{
m_bPortOpen=FALSE;
CloseHandle(m_hcom);
}
portstr.Format("\\\\.\\Com%d",m_ComPort);
if ((m_hcom=CreateFile( portstr, GENERIC_READ|GENERIC_WRITE,
0, // exclusive access
NULL, // no security attrs
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_OVERLAPPED, // overlapped I/O
NULL )) == (HANDLE) -1 )
{
return ( FALSE ) ;
}
// setup device buffers
SetupComm( m_hcom, 4096, 4096 ) ;
dcb.DCBlength = sizeof( DCB ) ;
GetCommState( m_hcom, &dcb );
dcb.BaudRate =m_ComBitRate;
dcb.ByteSize =8 ;
dcb.Parity = NOPARITY ;
dcb.StopBits = ONESTOPBIT ;
// setup hardware flow control
dcb.fOutxDsrFlow =FALSE ;
dcb.fDtrControl = DTR_CONTROL_ENABLE ;
dcb.fOutxCtsFlow = FALSE ;
dcb.fRtsControl = RTS_CONTROL_ENABLE ;
// setup software flow control
// other various settings
dcb.fBinary = TRUE ;
// dcb.fParity = FALSE ;
if(!SetCommState(m_hcom, &dcb ) )
{
return(FALSE);
}
//SetCommMask(m_hComm, EV_RXCHAR);
m_bPortOpen=TRUE;
if(!SetCommMask( m_hcom, EV_RXCHAR ))
return(FALSE);
else
return(TRUE);
}
//关闭串口
void CComPort::Close()
{
if(!m_bPortOpen)
return;
if (m_hcom != INVALID_HANDLE_VALUE)
::CloseHandle(m_hcom);
m_bPortOpen=FALSE;
}
//读串口
int CComPort::ReadComm(BYTE* MyBuff, int rCount)
{
BOOL fReadStat ;
COMSTAT ComStat ;
DWORD dwErrorFlags;
DWORD dwLength;
DWORD dwError;
// only try to read number of bytes in queue
ClearCommError( m_hcom, &dwErrorFlags, &ComStat ) ;
dwLength = min( (DWORD)rCount, ComStat.cbInQue ) ;
if (dwLength > 0)
{
fReadStat = ReadFile( m_hcom, MyBuff,
dwLength, &dwLength, &m_osRead ) ;
if (!fReadStat)
{
dwError = GetLastError();
if (GetLastError() == ERROR_IO_PENDING)
{
// We have to wait for read to complete.
// This function will timeout according to the
// CommTimeOuts.ReadTotalTimeoutConstant variable
// Every time it times out, check for port errors
while(!GetOverlappedResult( m_hcom ,
&m_osRead, &dwLength, TRUE ))
{
dwError = GetLastError();
if(dwError == ERROR_IO_INCOMPLETE)
// normal result if not finished
continue;
else
{
// an error occurred, try to recover
ClearCommError( m_hcom, &dwErrorFlags, &ComStat ) ;
}
}
}
else
{
// some other error occurred
dwLength = 0 ;
ClearCommError( m_hcom, &dwErrorFlags, &ComStat ) ;
}
}
}
return ( dwLength ) ;
}
//写串口
BOOL CComPort::WriteComm(BYTE * MyBuff, int wCount)
{
BOOL fWriteStat ;
DWORD dwBytesWritten ;
DWORD dwErrorFlags;
DWORD dwError;
DWORD dwBytesSent=0;
COMSTAT ComStat;
fWriteStat = WriteFile( m_hcom, MyBuff, wCount,
&dwBytesWritten, &m_osWrite ) ;
if (!fWriteStat)
{
if(GetLastError() == ERROR_IO_PENDING)
{
while(!GetOverlappedResult( m_hcom,
&m_osWrite, &dwBytesWritten, TRUE ))
{
dwError = GetLastError();
if(dwError == ERROR_IO_INCOMPLETE)
{
// normal result if not finished
dwBytesSent += dwBytesWritten;
continue;
}
else
{
ClearCommError( m_hcom, &dwErrorFlags, &ComStat ) ;
break;
}
}
dwBytesSent += dwBytesWritten;
}
else
{
// some other error occurred
ClearCommError( m_hcom, &dwErrorFlags, &ComStat ) ;
return ( FALSE );
}
}
return ( TRUE ) ;
}
//从串口读数据
void CComPort::ReadComData()
{
// BYTE TmpBuffReadData[m_MaxTableLen];
int datLength;
if(!m_bPortOpen)
return;
datLength=ReadComm(TmpBuffReadData,m_MaxTableLen);
while(datLength>0)
{
MyComBuff.SaveBuff(TmpBuffReadData,datLength);
datLength=ReadComm(TmpBuffReadData,m_MaxTableLen);
}
::SetEvent(m_hProcessEvent);
return;
}
//外部线程只需要调用GetTable()即可完成通信端口表格的处理
//GetTable()把不需要转发的通信协议表格自己自动处理
//需要转发的表格通过pRegionSocket指针转发出去
//具体的通信协议语义的处理由该过程负责
BOOL CComPort::ProcessTable()
{
// BYTE rBuff[m_MaxTableLen];
// int rCount;
COleDateTime tgps;
while (MyComBuff.GetTab(&tgps))
{
igps=0;
COleDateTimeSpan tspan;
COleDateTime pTime;
pTime = COleDateTime::GetCurrentTime();
tspan=pTime-tgps;
//误差10分钟才对时
// TRACE("%d-%d-%d %d:%d:%d \n ",tgps.GetYear(),tgps.GetMonth(),tgps.GetDay(),tgps.GetHour(),tgps.GetMinute(),tgps.GetSecond());
double dl;
dl=tspan.GetTotalSeconds();
if(dl!= 0 && dl>-600 && dl<600)
{
SYSTEMTIME st;
st.wYear = tgps.GetYear();
st.wMonth = tgps.GetMonth();
st.wDay = tgps.GetDay();
st.wHour = tgps.GetHour();
st.wMinute = tgps.GetMinute();
st.wSecond = tgps.GetSecond();
st.wMilliseconds = 0;
st.wDayOfWeek = 0;
SetLocalTime(&st);
sgps.Format("对时前%s 对时后%s",pTime.Format("%H:%M:%S"),tgps.Format("%H:%M:%S"));
}
}
return(TRUE);
}
//把未打包的表格打包后发送
BOOL CComPort::SendTable(BYTE *tabBuff, int tabCount)
{
//lv test 060808
long ltime,ltime2;
ltime=GetTickCount();
// BYTE TmpBuff[m_MaxTableLen];
int i,packLength;
if(!m_bPortOpen)
return(FALSE);
if(tabCount>m_MaxTableLen)//253)
return(FALSE);
for(i=0;i<tabCount;i++)
TmpBuff[i]=tabBuff[i];
if( (packLength=MyComBuff.PackTable(TmpBuff,tabCount))>0)
{
WriteComm(TmpBuff,packLength);
//lv test 060808
ltime2=GetTickCount();
ltime=ltime2-ltime;
if(ltime>10)
TRACE("CComPort::SendTable time %dms",ltime);
return(TRUE);
}
else
{
TRACE("CComPort::SendTable FALSE");
return(FALSE);
}
}
//给某个设备转发未打包的数据表格。处理:首先查找本端口是否包含该设备,然后打包,再发送
BOOL CComPort::TransmitTable( BYTE tDeviceNo, BYTE *sBuff, int sCount)
{
sBuff[5]=0;
sBuff[6]=tDeviceNo;
if(m_pOwner->m_pServerSocket->m_bAskConnect)
m_pOwner->m_pServerSocket->SendTable(sBuff,sCount);
return TRUE;
}
//发送应答请求连接
void CComPort::SendAck(BYTE sDeviceType,BYTE sDeviceNo)
{
BYTE sBuff[7];
sBuff[0]=0;
sBuff[1]=7;
sBuff[2]=RegionNo;
sBuff[3]=MainLinkCode;
sBuff[4]=AckCnt;
sBuff[5]=sDeviceType;
sBuff[6]=sDeviceNo;
SendTable(sBuff,7);
}
//发送查询请求连接
void CComPort::SendAckQry(BYTE sDeviceType,BYTE sDeviceNo)
{
BYTE sBuff[7];
sBuff[0]=0;
sBuff[1]=7;
sBuff[2]=RegionNo;
sBuff[3]=MainLinkCode;
sBuff[4]=AckQry;
sBuff[5]=sDeviceType;
sBuff[6]=sDeviceNo;
SendTable(sBuff,7);
}
//应答请求连接处理
void CComPort::AskCntProc(BYTE sDeviceType, BYTE sDeviceNo)
{
SendAck(sDeviceType,sDeviceNo);
if(!IsConnected)
{
BYTE b=1;
NotifyStatus(TRUE);//向中心发送
DWORD lParam= (LPARAM)MAKELONG(
MAKEWORD(m_ComPort,sDeviceNo),
MAKEWORD(b,0));
nTimeCount=0;
AfxGetMainWnd()->PostMessage(WM_COMMAND, IDM_LINKDEVUPDATE,lParam);
IsConnected=TRUE;
}
}
//应答查询连接
void CComPort::QryCmdProc(BYTE sDeviceType, BYTE sDeviceNo)
{
if(!IsConnected)
return;
nTimeCount=0;
SendAckQry(sDeviceType,sDeviceNo);
}
//waits for an event to occur for a specified communications device
void CComPort::WaitCommEvent()
{
ASSERT(m_osWait.hEvent != NULL);
ASSERT(m_hcom != INVALID_HANDLE_VALUE);
if (m_bPortOpen)
{
BOOL bRet = ::WaitCommEvent(m_hcom, &m_dwEventMask, &m_osWait);
if(!bRet)
{
long ErrNo=::GetLastError();
}
}
}
//向中心发送设备状态信息
void CComPort::NotifyStatus(BOOL iConnected)
{
if(m_pOwner->m_pServerSocket==NULL)
return;
if(!m_pOwner->m_pServerSocket->m_IsConnected )
return;
m_pOwner->m_pServerSocket->NotifyLineStatusTab(0,m_DeviceNo,iConnected);
}
//设置参数
void CComPort::SetPamera(BYTE Port, long BitRate,BYTE DeviceType,BYTE DeviceNo,CString Depict)
{
m_ComPort = Port;
m_ComBitRate = BitRate;
m_DeviceType= DeviceType;
m_DeviceNo =DeviceNo;
m_Depict = Depict;
}
void CComPort::AdjustDevConnect()
{
if(IsConnected)
{
nTimeCount++;
if(nTimeCount>TimeOutCount)
{
IsConnected = FALSE;
nTimeCount=-1;
NotifyStatus(FALSE);//设备的连接状态发生变化时向中心发送通知表格
DWORD lParam= (LPARAM)MAKELONG(
MAKEWORD(m_ComPort,m_DeviceNo),
MAKEWORD(0,0));
AfxGetMainWnd()->PostMessage(WM_COMMAND, IDM_LINKDEVUPDATE,lParam);
}
}
}
int CComPort::GetMyDeviceNo()
{
return(m_DeviceNo);
}
void CComPort::SendSelfControl()
{
BYTE sBuff[11];
sBuff[0]=0;
sBuff[1]=11;
sBuff[2]=RegionNo;
sBuff[3]=MainLinkCode;
sBuff[4]=ModeStageCmd;
sBuff[5]=m_DeviceType;
sBuff[6]=m_DeviceNo;
sBuff[7]=SelfControl;
sBuff[8]=0;
SendTable(sBuff,11);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -