📄 comm.cpp
字号:
unsigned int nBytelen;
DWORD nByteRead;
BOOL TraceFlagBak;
if(!fConnected) return(0);
nBytelen = 0;
GetCommTimeouts( hCom, &CommTimeOuts );
CommTimeOuts.ReadTotalTimeoutMultiplier = 10; //10ms timeout between two received chars
CommTimeOuts.ReadTotalTimeoutConstant = 300;
if((ByteTime!=0) && (ByteTime<10000))
CommTimeOuts.ReadTotalTimeoutConstant=ByteTime;
SetCommTimeouts( hCom, &CommTimeOuts );
TraceFlagBak=TraceFlag;
//zrz modyTraceFlag=FALSE;
TraceFlag = TRUE;
while(nBytelen<(str_room-1))
{
nByteRead=Read(&pReadBuf[nBytelen], 1);
if(nByteRead==1)
nBytelen += nByteRead;
else
break;
}
pReadBuf[nBytelen]=0;
TraceFlag=TraceFlagBak;
if(TraceFlag) CommTrace(Trace_File,pReadBuf,nBytelen,TraceMode,1);
return(nBytelen);
}
/*********************************************************************
Function: ReadComm
Description:串口读(非阻塞方式读串口,直到串口缓冲区中没有数据
或超时无数据)
Input: pReadBuf-->串口数据缓冲指针;
str_room-->串口数据缓冲空间大小;
HowTime-->设置串口读放弃时间;
ByteTime-->字节间隔最大时间(1--10000,default--300)
return: 串口实际读入数据个数
*********************************************************************/
int CCommDevice::ReadComm(char *pReadBuf,unsigned int str_room,DWORD HowTime,DWORD ByteTime)
{
int nReadLen,nBytelen;
if(!fConnected) return(-1);
nBytelen=0;
SetReadTimeOut(HowTime);
if(Read(pReadBuf,1)==1)
{
nReadLen=ReadBlock(&pReadBuf[1],str_room-1,ByteTime);
if(nReadLen>0)
nBytelen=1+nReadLen;
else if(nReadLen==0) nBytelen=1;
}
return(nBytelen);
}
/**********************************************************************
Function: EventRead
Description:串口事件读(阻塞方式读串口,直到串口缓冲区中没有数据
或超时无数据)
Input: pReadBuf-->串口数据缓冲指针;
str_room-->串口数据缓冲空间大小;
HowTime-->设置串口读放弃时间;
ByteTime-->字节间隔最大时间(1--10000,default--300)
return: 串口实际读入数据个数
***********************************************************************/
int CCommDevice::EventRead(char *lpszBlock,unsigned int str_room,DWORD HowTime,DWORD ByteTime)
{
DWORD dwEventMask,nByteRead;
unsigned int nBytelen;
if(!fConnected) return(-1);
HandleInfo.CommInfo = hCom;
KillTimeOutThread();
nBytelen = 0;
dwEventMask = 0;
if (!SetCommMask( hCom, EV_RXCHAR )) return(0);
if(HowTime>0)
{
HandleInfo.TimeOut = HowTime;
if(!CreateTimeOutThread(&HandleInfo))
{
SetCommMask(hCom,0);
return(-2);
}
}
while (HandleInfo.ThreadRun)
{
if(WaitCommEvent(hCom, &dwEventMask,NULL))
{
if((dwEventMask & EV_RXCHAR) == EV_RXCHAR)
{
HandleInfo.ThreadRun = FALSE;
SetCommMask(hCom,0);
GetCommTimeouts( hCom, &CommTimeOuts );
CommTimeOuts.ReadTotalTimeoutMultiplier = 10; //10ms timeout between two received chars
CommTimeOuts.ReadTotalTimeoutConstant = 300;
if((ByteTime!=0) && (ByteTime<10000))
CommTimeOuts.ReadTotalTimeoutConstant=ByteTime;
SetCommTimeouts( hCom, &CommTimeOuts );
while(nBytelen<(str_room-1))
{
nByteRead = 0;
nByteRead=Read(&lpszBlock[nBytelen], 1);
if(nByteRead==1)
nBytelen += nByteRead;
else
break;
}
}
}
}
SetCommMask( hCom, 0 );
lpszBlock[nBytelen] = 0;
if(TraceFlag) CommTrace(Trace_File,lpszBlock,nBytelen,TraceMode,1);
return(nBytelen);
}
/**********************************************************************
Function: CreateReadThread
Description:创建串口监控读线程
Input: lparam-->CommDevice 类对象
return: Fail-->false;Success-->非零
***********************************************************************/
BOOL CCommDevice::CreateReadThread(LPVOID lparam)
{
if(!fConnected) return(FALSE);
KillReadThread();
HandleInfo.ThreadRun = TRUE;
CRead_Thread = AfxBeginThread(ReadThread,lparam);
if (CRead_Thread==NULL)
{
HandleInfo.ThreadRun = FALSE;
}
else
{
EscapeCommFunction( hCom, SETDTR );
HandleInfo.ThreadRun = TRUE;
}
return(HandleInfo.ThreadRun);
}
/**********************************************************************
Function: CreateTimeOutThread
Description:创建串口事件读时间超时监控线程
Input: lparam-->CommDevice 类对象
return: Fail-->false;Success-->非零
***********************************************************************/
BOOL CCommDevice::CreateTimeOutThread(LPVOID lparam)
{
if(!fConnected) return(FALSE);
KillTimeOutThread();
HandleInfo.ThreadRun = TRUE;
CTimeOut = AfxBeginThread(TimeOutThread,lparam);
if (CTimeOut==NULL) HandleInfo.ThreadRun = FALSE;
else HandleInfo.ThreadRun = TRUE;
return(HandleInfo.ThreadRun);
}
/**********************************************************************
Function: KillReadThread
Description:清除串口监控读线程
***********************************************************************/
void CCommDevice::KillReadThread(void)
{
if(CRead_Thread)
{
if(HandleInfo.ThreadRun)
{
HandleInfo.ThreadRun = FALSE;
SetCommMask( hCom, 0);
CRead_Thread = NULL;
}
}
}
/**********************************************************************
Function: KillTimeOutThread
Description:清除串口时间读超时监控线程
***********************************************************************/
void CCommDevice::KillTimeOutThread(void)
{
if(CTimeOut)
{
if(HandleInfo.ThreadRun)
{
HandleInfo.ThreadRun = FALSE;
SetCommMask( hCom, 0);
CTimeOut = NULL;
}
}
}
/**********************************************************************
Function: PurgeCommBuf
Description:清串口缓冲
Input: InOutBufFlag-->串口缓冲[输入(0)/输出]标志
***********************************************************************/
void CCommDevice::PurgeCommBuf(int InOutBufFlag)
{
if(InOutBufFlag)
PurgeComm(hCom,PURGE_TXCLEAR);
else
PurgeComm(hCom,PURGE_RXCLEAR);
}
/**********************************************************************
Function: PutTraceFile
Description:初始化Trace参数
Input: FileStr-->录入文件名;
WriteMode-->录入模式;
(0---original data mode;1---Hexadecimal data mode)
return:
***********************************************************************/
void CCommDevice::PutTraceFile(char* FileStr,int WriteMode)
{
char* pDest;
//zrz modyTraceFlag=FALSE;
TraceFlag = TRUE;
memset(Trace_File,0,sizeof(Trace_File));
if(FileStr!=NULL)
{
pDest = strrchr(FileStr,'\\');
if(pDest!=NULL)
strcpy(FileStr,pDest+1);
if(strlen(FileStr)>0)
{
pDest = strchr(FileStr,'.');
if(pDest!=NULL)
{
if(pDest!=FileStr)
{
strncpy(Trace_File,FileStr,pDest-FileStr);
TraceMode = WriteMode;
TraceFlag = TRUE;
}
}
else
{
strcpy(Trace_File,FileStr);
TraceMode = WriteMode;
TraceFlag = TRUE;
}
}
}
}
/**********************************************************************
Function: CommTrace
Description:搜寻子串(SearchBuf)在串(SourceBuf)中的位置
Input: file_name-->Trace File Name;
TraceStr-->录入串;
WriteLen-->录入原串长;
WriteMode-->录入模式;
RS_flag-->receive or send or other
(0--send;1--receive;2--other)
return:
***********************************************************************/
void CCommDevice::CommTrace(char* file_name,char* TraceStr,DWORD WriteLen,int WriteMode,int RS_flag)
{
char Tmp_File[50],CurrentDate[16],FileDate[16];
char WriteBuf[100];
CStdioFile TraceFile;
CFileStatus rStatus;
CTime Today;
int TotalWrite;
if((TraceStr==NULL) || (WriteLen==0) || (strlen(Trace_File)==0)) return;
Today=CTime::GetCurrentTime();
TotalWrite=(int)WriteLen;
if(!strcmp(file_name,Trace_File))
sprintf(Tmp_File,".\\trace\\%s%s.txt",file_name,Today.Format("%w"));
else
strcpy(Tmp_File,file_name);
sprintf(CurrentDate,"%s",Today.Format("%d"));
if(TraceFile.GetStatus(Tmp_File, rStatus ))
{
sprintf(FileDate,"%s",rStatus.m_mtime.Format("%d"));
if(strcmp(FileDate,CurrentDate))
{
if(!TraceFile.Open(Tmp_File,CFile::modeCreate|CFile::modeWrite)) return;
}
else
{
if(!TraceFile.Open(Tmp_File,CFile::modeWrite)) return;
}
}
else
{
if(!TraceFile.Open(Tmp_File,CFile::modeCreate|CFile::modeWrite)) return;
}
if(TraceFile.GetLength()>64000) TraceFile.SetLength(0);
TraceFile.SeekToEnd();
if(RS_flag==1)
sprintf(WriteBuf,"Receive %02d/%02d/%02d RecvLen=%04d",Today.GetHour(),Today.GetMinute(),Today.GetSecond(),TotalWrite);
else if(RS_flag==0)
sprintf(WriteBuf,"Send %02d/%02d/%02d SendLen=%04d",Today.GetHour(),Today.GetMinute(),Today.GetSecond(),TotalWrite);
else
sprintf(WriteBuf,"Trace %02d/%02d/%02d TraceLen=%04d",Today.GetHour(),Today.GetMinute(),Today.GetSecond(),TotalWrite);
TraceFile.Write(WriteBuf,strlen(WriteBuf));
TraceFile.WriteString("\n");
if(WriteMode!=0)
{
int i,NumWrited,LeftLen,WriteNum;
NumWrited=0;
LeftLen=TotalWrite;
while(LeftLen>0)
{
if(LeftLen>20)
WriteNum=20;
else
WriteNum=LeftLen;
for(i=0;i<WriteNum;i++)
sprintf(&WriteBuf[3*i],"%02x ",(unsigned char)TraceStr[NumWrited++]);
WriteBuf[3*i]=0;
TraceFile.Write(WriteBuf,strlen(WriteBuf));
TraceFile.WriteString("\n");
LeftLen=TotalWrite-NumWrited;
}
}
else
{
if(strcmp(TraceStr,"\xa"))
{
TraceFile.Write(TraceStr,strlen(TraceStr));
}
TraceFile.WriteString("\n");
}
TraceFile.Close();
}
/**********************************************************************
Function: Close
Description:关闭串口
***********************************************************************/
void CCommDevice::Close()
{
if(!fConnected) return;
HandleInfo.ThreadRun = FALSE;
SetCommMask( hCom, 0 );
EscapeCommFunction( hCom, CLRDTR );
PurgeComm( hCom, PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR );
CloseHandle( hCom );
fConnected = FALSE;
ComPort[0]=0;
HandleInfo.ThreadRun = FALSE;
}
/**********************************************************************
Function: InStr
Description:搜寻子串(SearchBuf)在串(SourceBuf)中的位置
Input: SourceBuf-->被搜寻串;SearchBuf-->搜寻串
return: Fail-->-1;Success-->子串在串中的位置
***********************************************************************/
int CCommDevice::InStr(char *SourceBuf,char *SearchBuf)
{
int SourceLen,TargetLen,Times,i,j,k;
BOOL ContinueSearch;
if((SourceBuf==NULL) || (SearchBuf==NULL)) return(-1);
ContinueSearch = TRUE;
SourceLen = strlen(SourceBuf);
TargetLen = strlen(SearchBuf);
if((SourceLen==0) || (TargetLen==0) || (SourceLen<TargetLen))
return(-1);
Times = SourceLen-TargetLen;
for(i=0;(i<=Times) && ContinueSearch;i++)
{
k = 0;
for(j=0;j<TargetLen;j++)
{
if(SourceBuf[i+j]!=SearchBuf[j])
break;
else
{
k++;
if(k==TargetLen)
ContinueSearch=FALSE;
}
}
}
if(ContinueSearch) return(-1);
else return(i-1);
}
/**********************************************************************
Function: TrimLeft
Description:删除串(SourceBuf)左边的空格
Input: SourceBuf-->需删除左边空格的串
output: SourceBuf-->删除左边空格后的串
***********************************************************************/
void CCommDevice::TrimLeft(char *SourceBuf)
{
int SourceLen,i;
if(SourceBuf==NULL) return;
if((SourceLen=strlen(SourceBuf))==0) return;
i = 0;
while((SourceBuf[i]==32) && (i<SourceLen)) i++;
strcpy(SourceBuf,&SourceBuf[i]);
}
/**********************************************************************
Function: TrimRight
Description:删除串(SourceBuf)右边的空格
Input: SourceBuf-->需删除右边空格的串
output: SourceBuf-->删除右边空格后的串
***********************************************************************/
void CCommDevice::TrimRight(char *SourceBuf)
{
int SourceLen,i;
if(SourceBuf==NULL) return;
if((SourceLen=strlen(SourceBuf))==0) return;
i=SourceLen-1;
while((i>=0) && (SourceBuf[i]==32)) i--;
SourceBuf[i+1]='\0';
}
/**********************************************************************
Function: Intercept
Description:从母串(SourceStr)中将特征串(CmpStr)前的子串截下,放置在
变量(lpReturnedString)中
Input: nSize-->变量(lpReturnedString)大小;
return: Fail-->(<0);Success-->(>=0)
***********************************************************************/
int CCommDevice::Intercept(char *lpReturnedString,int nSize,char *SourceStr,char *CmpStr)
{
int pos,sourcelen,cmplen;
if((lpReturnedString==NULL) || (SourceStr==NULL) || (CmpStr==NULL)) return(-3);
lpReturnedString[0] = 0;
sourcelen = strlen(SourceStr);
cmplen = strlen(CmpStr);
if((sourcelen==0) || (cmplen==0) || (nSize<=0))
return(-2);
pos = InStr(SourceStr,CmpStr);
if(pos==0)
{
strcpy(SourceStr,&SourceStr[cmplen]);
lpReturnedString[0] = '\0';
return(0);
}
if(pos>=nSize) return(-1);
if(pos>0)
{
strncpy(lpReturnedString,SourceStr,pos);
lpReturnedString[pos] = '\0';
strcpy(SourceStr,&SourceStr[cmplen+pos]);
return(pos);
}
else if(nSize>sourcelen)
{
strcpy(lpReturnedString,SourceStr);
SourceStr[0] = '\0';
return(sourcelen);
}
return(-2);
}
/**********************************************************************
Function: ChangeStr
Description:将十进制串转换为相应的字符串
Input: CmpStr-->间隔串
***********************************************************************/
void CCommDevice::ChangeStr(char *lpReturnedString,char *SourceStr,char *CmpStr)
{
char databuf[50];
int p;
p = 0;
while(Intercept(databuf,(int)sizeof(databuf),SourceStr,CmpStr)>=0)
{
TrimLeft(databuf);
TrimRight(databuf);
if(strlen(databuf)>0)
lpReturnedString[p++] =(char)atoi(databuf);
}
lpReturnedString[p] = '\0';
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -