📄 serial.cpp
字号:
// Serial.cpp
#include "stdafx.h"
#include "Serial.h"
#include "public.h"
CSerial::CSerial()
{
memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );
m_hIDComDev = NULL;
m_bOpened = FALSE;
}
CSerial::~CSerial()
{
Close();
}
BOOL CSerial::Open( int nPort, int nBaud )
{
if( m_bOpened ) return( TRUE );
char szPort[15];
char szComParams[50];
DCB dcb;
wsprintf( szPort, "COM%d", nPort );
m_hIDComDev = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL );
if( m_hIDComDev == NULL ) return( FALSE );
memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );
COMMTIMEOUTS CommTimeOuts;
CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant = 5000;
SetCommTimeouts( m_hIDComDev, &CommTimeOuts );
wsprintf( szComParams, "COM%d:%d,n,8,1", nPort, nBaud );
m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
dcb.DCBlength = sizeof( DCB );
GetCommState( m_hIDComDev, &dcb );
dcb.BaudRate = nBaud;
dcb.ByteSize = 8;
unsigned char ucSet;
ucSet = (unsigned char) ( ( FC_RTSCTS & FC_DTRDSR ) != 0 );
ucSet = (unsigned char) ( ( FC_RTSCTS & FC_RTSCTS ) != 0 );
ucSet = (unsigned char) ( ( FC_RTSCTS & FC_XONXOFF ) != 0 );
if( !SetCommState( m_hIDComDev, &dcb ) ||
!SetupComm( m_hIDComDev, 10000, 10000 ) ||
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_hIDComDev );
return( FALSE );
}
m_bOpened = TRUE;
return( m_bOpened );
}
BOOL CSerial::Close( void )
{
if( !m_bOpened || m_hIDComDev == NULL ) return( TRUE );
if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
CloseHandle( m_hIDComDev );
m_bOpened = FALSE;
m_hIDComDev = NULL;
return( TRUE );
}
BOOL CSerial::WriteCommByte( unsigned char ucByte )
{
BOOL bWriteStat;
DWORD dwBytesWritten;
bWriteStat = WriteFile( m_hIDComDev, (LPSTR) &ucByte, 1, &dwBytesWritten, &m_OverlappedWrite );
if( !bWriteStat && ( GetLastError() == ERROR_IO_PENDING ) ){
if( WaitForSingleObject( m_OverlappedWrite.hEvent, 1000 ) ) dwBytesWritten = 0;
else{
GetOverlappedResult( m_hIDComDev, &m_OverlappedWrite, &dwBytesWritten, FALSE );
m_OverlappedWrite.Offset += dwBytesWritten;
}
}
return( TRUE );
}
int CSerial::SendData( const unsigned char *buffer, int size )
{
if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );
DWORD dwBytesWritten = 0;
int i;
for( i=0; i<size; i++ ){
WriteCommByte( buffer[i] );
dwBytesWritten++;
}
return( (int) dwBytesWritten );
}
int CSerial::ReadDataWaiting( void )
{
if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );
DWORD dwErrorFlags;
COMSTAT ComStat;
ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
return( (int) ComStat.cbInQue );
}
int CSerial::ReadData( void *buffer, int limit )
{
if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );
BOOL bReadStatus;
DWORD dwBytesRead, dwErrorFlags;
COMSTAT ComStat;
ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
if( !ComStat.cbInQue ) return( 0 );
dwBytesRead = (DWORD) ComStat.cbInQue;
if( limit < (int) dwBytesRead ) dwBytesRead = (DWORD) limit;
bReadStatus = ReadFile( m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );
if( !bReadStatus ){
if( GetLastError() == ERROR_IO_PENDING ){
WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
return( (int) dwBytesRead );
}
return( 0 );
}
return( (int) dwBytesRead );
}
int CSerial::SendPacket(unsigned char *buf, int packlen)
{
unsigned char buffer[1024];
int i;
char tmp[4];
if(packlen > 1000)
return 0;
buffer[0] = 0x02;
sprintf(tmp, "%04d", packlen);
buffer[1] = (tmp[0]<<4)+(tmp[1]&0x0f);
buffer[2] = (tmp[2]<<4)+(tmp[3]&0x0f);
memcpy(buffer+0, buf, packlen);
buffer[packlen+0] = 0x03;
buffer[packlen+0] = 0;
for(i=1;i<packlen+0;i++)
buffer[packlen+0] ^= buffer[i];
for(i=0;i<packlen+5;i++)
sprintf(tmp+2*i, "%02x", buffer[i]);
AfxMessageBox(tmp);
if(SendData((unsigned char*)buffer, packlen+0) != packlen+5)
return 0;
return packlen;
}
int CSerial::SendACK()
{
unsigned char buffer[1024];
buffer[0] = 0x06;
if(SendData((unsigned char*)buffer, 1) != 1)
return -1;
return 0;
}
int CSerial::SendPack(int PackCode, int TicketId)
{
unsigned char buffer[1024];
int i, packlen;
int mask = 0x8000;
int GetElse = 0x7FFF;
int count = 0;
int temp = 0;
int len = 0;
char tempstr[20];
memset(buffer, 0, sizeof(buffer));
buffer[0] = 0x02; //---<STX>
buffer[1] = 0x1C; //---<FS>
sprintf(tempstr, "%d", PackCode);
memcpy((char *)(buffer+2), tempstr, strlen(tempstr)); //--PackCode
buffer[5] = 0x1F; //---<US>
if (PackCode == 332)
{
memcpy(buffer+6,"AA", 2);
buffer[8] = 29;
char temp[20];
//memcpy(buffer+9, "BCCB#INFO", 9);
sprintf(temp, "BCCB#%d", TicketId);
memcpy(buffer+9, temp, strlen(temp));
packlen = strlen((char *)buffer)+2;
}
if (PackCode == 333)
{
memcpy(buffer+6, "AA", 2);
buffer[8] = 29;
char temp[20];
sprintf(temp, "BCCB#%d", TicketId);
memcpy(buffer+9, temp, strlen(temp));
packlen = strlen((char *)buffer)+2;
}
buffer[packlen - 2] = 0x1C;
buffer[packlen - 1] = 0x03; //---<ETX>
for(i=1 ;i <= packlen ; i++)
count = count + buffer[i];
if (count > 0xFF)
{
if ((count & 0xFF) & 0x80)
buffer[packlen]= count & 0x7F;
else
buffer[packlen]= count & 0xF7F;
}
else
{
for (i=0 ; i < 16 ; i++, mask >>=1 , GetElse >>=1)
{
if (count & mask) //如果与mask大与零,则取最高位后的所有的位
{
temp = count & GetElse;
buffer[packlen] = temp;
break;
}
}
}
if(SendData((unsigned char*)buffer, packlen+1) != packlen+1)
return -1;
SetListInfo((char *)buffer);
return packlen+1;
}
int CSerial::ReceivePacket(unsigned char *buf)
{
unsigned char buffer[1024];
char tmp[1000];
int packlen,len,len1,i;
CString b;
DWORD timeout;
memset(buffer, 0, sizeof(buffer));
len = len1 = 0;
do{
ReadData(buffer+len, 1);
}while(buffer[0] != 0x02);
for(i=1;i<3;i++)
ReadData(buffer+i, 1);
tmp[0] = (buffer[1]>>4)+'0';
tmp[1] = (buffer[1]&0x0f)+'0';
tmp[2] = (buffer[2]>>4)+'0';
tmp[3] = (buffer[2]&0x0f)+'0';
tmp[4] = 0;
packlen = atoi(tmp);
if(packlen > 1000)
return 0;
timeout = GetTickCount();
len = 3;
do{
len1 = ReadData(buffer+len, 1024);
len += len1;
if((GetTickCount()-timeout)>2000)
{AfxMessageBox("TimeOut!");return(0);}
}while(len < packlen+5);
/*
for(i=0;i<packlen+5;i++)
sprintf(tmp+2*i, "%02x", buffer[i]);
AfxMessageBox(tmp);
*/
buffer[1023] = 0;
for(i=1;i<packlen+4;i++)
buffer[1023] ^= buffer[i];
if(buffer[1023] != buffer[packlen+4])
{AfxMessageBox("LRC ERROR!");return 0;}
memcpy(buf, buffer+3, len-5);
return packlen;
}
int CSerial::ReceivePack(unsigned char *buf)
{
unsigned char buffer[3000];
char tmp[1000];
int len,len1,i;
CString b;
DWORD timeout;
int mask = 0x8000;
int GetElse = 0x7FFF;
int GetCheckNumber = 0xFF; //Get 8 bit
int count = 0; //从STX后一位到ETX的总和
int temp; //两者进行与以后大于零时的总次数;
memset(buffer, 0, sizeof(buffer));
memset(tmp, 0, sizeof(tmp));
len = len1 = 0;
//接收包头字符
do{
ReadData(buffer+len, 1);
}while(buffer[0] != 0x02);
timeout = GetTickCount();
len1= len = 1;
do
{
len1 = ReadData(buffer+len, 1);
len += len1;
if((GetTickCount()-timeout)>1000)
break;
}
while(buffer[len-1] != 3);
ReadData(buffer+len, 1);
//取包文所有字符的和
for(i=1; i < len ; i++)
count = count + buffer[i];
int Begin8Bit;
Begin8Bit = count & GetCheckNumber;
if (count > GetCheckNumber)
count = count & GetCheckNumber;
memcpy(buf, buffer, len+1);
if (buffer[len] == Begin8Bit || buffer[len] == count || buffer[len] == 0)
return len+1;
for (i=0 ; i < 16 ; i++, mask >>=1 , GetElse >>=1)
{
if (count & mask) //如果与mask大与零,则取最高位后的所有的位
{
temp = count & GetElse;
if (buffer[len] == temp )
break;
else
{
SetListInfo("包文错误!");
//return -1;
}
}
}
return len+1;
}
int CSerial::ReceiveACK()
{
DWORD timeout;
unsigned char buffer[3000];
timeout = GetTickCount();
do{
ReadData(buffer, 1);
if((GetTickCount()-timeout)>1000)
return -1;
}while(buffer[0] != 0x06);
return 0;
}
int CSerial::UnpackRecData(unsigned char * buffer, int packlen, long TicketNumber)
{
FILE *fp;
char filename[80],pathname[80], temp[80];
int TicketId=0;
bool BeginRec=false;
int first=0, last=0;
int LineCount=0;
memset(temp, 0, sizeof(temp));
memcpy(temp, (char *)(buffer+2), 3);
if (atoi(temp) != 340)
return atoi(temp);
memset(pathname, 0, sizeof(pathname));
if (GetPrivateProfileString("FILE", "PackDataFilePath ", NULL, pathname, sizeof(pathname), ".\\config.ini") < 0)
{
AfxMessageBox("Cann't open config file!");
return -1;
}
memset(filename, 0, sizeof(filename));
sprintf(filename, "%s\\%06ld.txt", pathname, TicketNumber);
if ((fp = fopen(filename, "wb")) == NULL)
{
sprintf(temp, "打不开文件%s!", filename);
SetListInfo(temp);
return -1;
}
for(int i=0 ; i< packlen; i++)
{
if (buffer[i] == 0x03)
break;
if (buffer[i] == 0x1C)
continue;
if (buffer[i] == 0x1E && first < last)
{
memset(temp, 0, sizeof(temp));
memcpy(temp, buffer+first, i - first );
for(int j=0; j< (int)strlen(temp); j++)
{
if(temp[j] == 0x1F) //<US> to blank
temp[j] = ' ';
}
fprintf(fp, "%s\n", temp);
LineCount ++; //计算写入文件的行数
}
if (buffer[i] == 0x1E ) //<RS>
{
//if(first == last && first == 0)
first = last = i+1;
BeginRec = true;
continue;
}
if (BeginRec == true)
last ++;
}
fclose(fp);
return 340;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -