// ProtocolPMC916.cpp: implementation of the CProtocolModbus class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ProtocolModbus.h" #include "winsock2.h" #include "Gree.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif char Hex16(char WillChangeNum[]) //该函数把四位二进制转换成十六进制数 { int i; i = (WillChangeNum[3]) + (WillChangeNum[2] * 10) + (WillChangeNum[1] * 100) + (WillChangeNum[0] * 1000); switch(i) { case 0: return 0; case 1: return 1; case 10: return 2; case 11: return 3; case 100: return 4; case 101: return 5; case 110: return 6; case 111: return 7; case 1000: return 8; case 1001: return 9; case 1010: return 0x0A; case 1011: return 0x0B; case 1100: return 0x0C; case 1101: return 0x0D; case 1110: return 0x0E; case 1111: return 0x0F; } return -1; } void Binary2(BYTE WillChangeNum, char *pResult) //该函数把十六进制数转换成四位二进制 { char ch[4] = {0}; switch(WillChangeNum) { case '0': *pResult = 0; *(pResult + 1) = 0; *(pResult + 2) = 0; *(pResult + 3) = 0; break; case '1': *pResult = 0; *(pResult + 1) = 0; *(pResult + 2) = 0; *(pResult + 3) = 1; break; case '2': *pResult = 0; *(pResult + 1) = 0; *(pResult + 2) = 1; *(pResult + 3) = 0; break; case '3': *pResult = 0; *(pResult + 1) = 0; *(pResult + 2) = 1; *(pResult + 3) = 1; break; case '4': *pResult = 0; *(pResult + 1) = 1; *(pResult + 2) = 0; *(pResult + 3) = 0; break; case '5': *pResult = 0; *(pResult + 1) = 1; *(pResult + 2) = 0; *(pResult + 3) = 1; break; case '6': *pResult = 0; *(pResult + 1) = 1; *(pResult + 2) = 1; *(pResult + 3) = 0; break; case '7': *pResult = 0; *(pResult + 1) = 1; *(pResult + 2) = 1; *(pResult + 3) = 1; break; case '8': *pResult = 1; *(pResult + 1) = 0; *(pResult + 2) = 0; *(pResult + 3) = 0; break; case '9': *pResult = 1; *(pResult + 1) = 0; *(pResult + 2) = 0; *(pResult + 3) = 1; break; case 'A': *pResult = 1; *(pResult + 1) = 0; *(pResult + 2) = 1; *(pResult + 3) = 0; break; case 'B': *pResult = 1; *(pResult + 1) = 0; *(pResult + 2) = 1; *(pResult + 3) = 1; break; case 'C': *pResult = 1; *(pResult + 1) = 1; *(pResult + 2) = 0; *(pResult + 3) = 0; break; case 'D': *pResult = 1; *(pResult + 1) = 1; *(pResult + 2) = 0; *(pResult + 3) = 1; break; case 'E': *pResult = 1; *(pResult + 1) = 1; *(pResult + 2) = 1; *(pResult + 3) = 0; break; case 'F': *pResult = 1; *(pResult + 1) = 1; *(pResult + 2) = 1; *(pResult + 3) = 1; break; } } void TenHex16(int idnum,char *outchar) //参数是需要转换成16进制数的十进制数 { char TwoHex[100]; //数组存放二进制数 char Willchange[4]; //每次以4位二进制数为一组 进行十六进制转换 memset(TwoHex,0,100); memset(Willchange,0,4); int i=0; //位数 bool HeightBit=0; for (;;) //转换成二进制 { if (idnum==1) { TwoHex[i]=1; i++; break; } else { TwoHex[i]=idnum%2; idnum=idnum/2; } i++; } if (i%2==1) //如果是奇数位则补0 //保证是四位的倍数 后面好处理 { i++; TwoHex[i]=0; } int p=0; for (int num=0;num>= 1; } return b; } ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CProtocolModbus::CProtocolModbus() : CProtocol() { InitializeCriticalSection( &m_csReadFinished ); InitializeCriticalSection( &m_csWrFinished ); MTVERIFY( m_hSemComm = CreateEvent( NULL, TRUE, TRUE, 0 ) ); } CProtocolModbus::~CProtocolModbus() { DeleteCriticalSection( &m_csReadFinished ); DeleteCriticalSection( &m_csWrFinished ); MTVERIFY( CloseHandle( m_hSemComm ) ); } int CProtocolModbus::WorkMain(int nAddr, int nDataLen,int nReadPos, char chMsg[80]) { if(!m_pComm) return ERR_CODE_GREE_COM_FAULT; // 串口通信故障 int nRet; #if 0 nRet = RequestStatus(nAddr); if( nRet != 0 ) { return nRet; // 串口忙 } nRet = ResponseStatus(nAddr, nDataLen, nReadPos, chMsg); #else nRet = ResponseStatus(nAddr, nDataLen, nReadPos, chMsg); #endif return nRet; } int CProtocolModbus:: WriteCommand( int nAddr, int nWorkStatus, int nWorkMode, int nFanSpeed, int nPutWind, int nAirTrade, int nSleep, int nLight, int nTempSetPoint ) { int iResult = 0; if(!m_pComm) return ERR_CODE_GREE_COM_FAULT; iResult = RequestWrStatus( nAddr, nWorkStatus, nWorkMode, nFanSpeed, nPutWind, nAirTrade, nSleep, nLight, nTempSetPoint ); if (iResult == 0) return ResponseWrStatus( nAddr, nWorkStatus, nWorkMode, nFanSpeed, nPutWind, nAirTrade, nSleep, nLight, nTempSetPoint ); else return iResult; } int CProtocolModbus::RequestWrStatus( int nAddr, int nWorkStatus, int nWorkMode, int nFanSpeed, int nPutWind, int nAirTrade, int nSleep, int nLight, int nTempSetPoint ) { //TRACE3("=============WorkStatus = %d, WorkMode = %d, FanSpeed = %d\n", // nWorkStatus, nWorkMode, nFanSpeed); //TRACE3("=============PutWind=%d, AirTrade=%d, Sleeep = %d\n", nPutWind, nAirTrade, nSleep); //TRACE2("=============Light=%d, TempSetPoint=%d\n", nLight, nTempSetPoint); REQUESTPARAM tagRequest; int nLen = sizeof(REQUESTPARAM); memset( &tagRequest, 0, nLen ); tagRequest.btStart = 0x07; tagRequest.szAddr[0] = ByteToAscii( (nAddr >> 12) & 0x000F ); tagRequest.szAddr[1] = ByteToAscii( (nAddr >> 8) & 0x000F ); tagRequest.szAddr[2] = ByteToAscii( (nAddr >> 4) & 0x000F ); tagRequest.szAddr[3] = ByteToAscii( nAddr & 0x000F ); for( int i = 0; i < 8; i++ ) { tagRequest.szRsCode[i] = ByteToAscii(0); } char chBuffer1High[4]; memset(chBuffer1High, 0, sizeof(chBuffer1High)); char chBuffer1Low[4]; memset(chBuffer1Low, 0, sizeof(chBuffer1Low)); char chBuffer2High[4]; memset(chBuffer2High, 0, sizeof(chBuffer2High)); char chBuffer2Low[4]; memset(chBuffer2Low, 0, sizeof(chBuffer2Low)); char chBuffer3High[4]; memset(chBuffer3High, 0, sizeof(chBuffer3High)); char chBuffer3Low[4]; memset(chBuffer3Low, 0, sizeof(chBuffer3Low)); char chBuffer4High[4]; memset(chBuffer4High, 0, sizeof(chBuffer4High)); char chBuffer4Low[4]; memset(chBuffer4Low, 0, sizeof(chBuffer4Low)); RsCode1 tagRsCode1; memset(&tagRsCode1, 0, sizeof(RsCode1)); RsCode2 tagRsCode2; memset(&tagRsCode2, 0, sizeof(RsCode2)); RsCode3 tagRsCode3; memset(&tagRsCode3, 0, sizeof(RsCode3)); RsCode4 tagRsCode4; memset(&tagRsCode4, 0, sizeof(RsCode4)); tagRsCode1.szStatus = 1; //这里为设置状态 // 空调开机=1/关机=0 switch( nWorkStatus ) { case 0: tagRsCode1.szMode[3] = 0; tagRsCode1.szMode[0] = 0; tagRsCode1.szMode[1] = 0; tagRsCode1.szMode[2] = 0; break; case 1: tagRsCode1.szMode[0] = 1; // 空调工作模式(0:自动, 1:制冷, 2:抽湿, 3:送风 4:制热) switch( nWorkMode ) { case 0: tagRsCode1.szMode[1] = 0; tagRsCode1.szMode[2] = 0; tagRsCode1.szMode[3] = 0; break; case 1: tagRsCode1.szMode[1] = 0; tagRsCode1.szMode[2] = 0; tagRsCode1.szMode[3] = 1; break; case 2: tagRsCode1.szMode[1] = 0; tagRsCode1.szMode[2] = 1; tagRsCode1.szMode[3] = 0; break; case 3: tagRsCode1.szMode[1] = 0; tagRsCode1.szMode[2] = 1; tagRsCode1.szMode[3] = 1; break; case 4: tagRsCode1.szMode[1] = 1; tagRsCode1.szMode[2] = 0; tagRsCode1.szMode[3] = 0; break; } break; } memcpy(chBuffer1High, &tagRsCode1, sizeof(chBuffer1High)); memcpy(chBuffer1Low, ((char *)&tagRsCode1) + sizeof(chBuffer1High), sizeof(chBuffer1Low)); tagRequest.szRsCode[0] = Hex16(chBuffer1High) + '0'; tagRequest.szRsCode[1] = Hex16(chBuffer1Low) + '0'; // 设定温度 switch(nTempSetPoint) { case 16: tagRsCode2.szTempSetPoint[0] = 0; tagRsCode2.szTempSetPoint[1] = 0; tagRsCode2.szTempSetPoint[2] = 0; tagRsCode2.szTempSetPoint[3] = 0; break; case 17: tagRsCode2.szTempSetPoint[0] = 0; tagRsCode2.szTempSetPoint[1] = 0; tagRsCode2.szTempSetPoint[2] = 0; tagRsCode2.szTempSetPoint[3] = 1; break; case 18: tagRsCode2.szTempSetPoint[0] = 0; tagRsCode2.szTempSetPoint[1] = 0; tagRsCode2.szTempSetPoint[2] = 1; tagRsCode2.szTempSetPoint[3] = 0; break; case 19: tagRsCode2.szTempSetPoint[0] = 0; tagRsCode2.szTempSetPoint[1] = 0; tagRsCode2.szTempSetPoint[2] = 1; tagRsCode2.szTempSetPoint[3] = 1; break; case 20: tagRsCode2.szTempSetPoint[0] = 0; tagRsCode2.szTempSetPoint[1] = 1; tagRsCode2.szTempSetPoint[2] = 0; tagRsCode2.szTempSetPoint[3] = 0; break; case 21: tagRsCode2.szTempSetPoint[0] = 0; tagRsCode2.szTempSetPoint[1] = 1; tagRsCode2.szTempSetPoint[2] = 0; tagRsCode2.szTempSetPoint[3] = 1; break; case 22: tagRsCode2.szTempSetPoint[0] = 0; tagRsCode2.szTempSetPoint[1] = 1; tagRsCode2.szTempSetPoint[2] = 1; tagRsCode2.szTempSetPoint[3] = 0; break; case 23: tagRsCode2.szTempSetPoint[0] = 0; tagRsCode2.szTempSetPoint[1] = 1; tagRsCode2.szTempSetPoint[2] = 1; tagRsCode2.szTempSetPoint[3] = 1; break; case 24: tagRsCode2.szTempSetPoint[0] = 1; tagRsCode2.szTempSetPoint[1] = 0; tagRsCode2.szTempSetPoint[2] = 0; tagRsCode2.szTempSetPoint[3] = 0; break; case 25: tagRsCode2.szTempSetPoint[0] = 1; tagRsCode2.szTempSetPoint[1] = 0; tagRsCode2.szTempSetPoint[2] = 0; tagRsCode2.szTempSetPoint[3] = 1; break; case 26: tagRsCode2.szTempSetPoint[0] = 1; tagRsCode2.szTempSetPoint[1] = 0; tagRsCode2.szTempSetPoint[2] = 1; tagRsCode2.szTempSetPoint[3] = 0; break; case 27: tagRsCode2.szTempSetPoint[0] = 1; tagRsCode2.szTempSetPoint[1] = 0; tagRsCode2.szTempSetPoint[2] = 1; tagRsCode2.szTempSetPoint[3] = 1; break; case 28: tagRsCode2.szTempSetPoint[0] = 1; tagRsCode2.szTempSetPoint[1] = 1; tagRsCode2.szTempSetPoint[2] = 0; tagRsCode2.szTempSetPoint[3] = 0; break; case 29: tagRsCode2.szTempSetPoint[0] = 1; tagRsCode2.szTempSetPoint[1] = 1; tagRsCode2.szTempSetPoint[2] = 0; tagRsCode2.szTempSetPoint[3] = 1; break; case 30: tagRsCode2.szTempSetPoint[0] = 1; tagRsCode2.szTempSetPoint[1] = 1; tagRsCode2.szTempSetPoint[2] = 1; tagRsCode2.szTempSetPoint[3] = 0; break; } // 风速(自动=0, 低风=1, 中风=2, 高风=3) switch(nFanSpeed) { case 0: tagRsCode2.szFanSpeed[0] = 0; tagRsCode2.szFanSpeed[1] = 0; break; case 1: tagRsCode2.szFanSpeed[0] = 0; tagRsCode2.szFanSpeed[1] = 1; break; case 2: tagRsCode2.szFanSpeed[0] = 1; tagRsCode2.szFanSpeed[1] = 0; break; case 3: tagRsCode2.szFanSpeed[0] = 1; tagRsCode2.szFanSpeed[1] = 1; break; } // 扫风 switch(nPutWind) { case 0: tagRsCode2.szPutWind = 0; break; case 1: tagRsCode2.szPutWind = 1; break; } // 睡眠 switch(nSleep) { case 0: tagRsCode2.szSleep = 0; break; case 1: tagRsCode2.szSleep = 1; break; } memcpy(chBuffer2High, &tagRsCode2, sizeof(chBuffer2High)); memcpy(chBuffer2Low, ((char *)&tagRsCode2) + sizeof(chBuffer2High), sizeof(chBuffer2Low)); tagRequest.szRsCode[2] = Hex16(chBuffer2High) + '0'; tagRequest.szRsCode[3] = Hex16(chBuffer2Low) + '0'; // 3byte为定时,暂不做处理 memset(&tagRsCode3, 0, sizeof(tagRsCode3)); tagRequest.szRsCode[4] = ByteToAscii(0); tagRequest.szRsCode[5] = ByteToAscii(0); // 灯光 switch(nLight) { case 0: tagRsCode4.szLight = 0; break; case 1: tagRsCode4.szLight = 1; break; } // 换气 switch(nAirTrade) { case 0: tagRsCode4.szTradeAir[0] = 0; tagRsCode4.szTradeAir[1] = 0; break; case 1: tagRsCode4.szTradeAir[0] = 0; tagRsCode4.szTradeAir[1] = 1; break; case 2: tagRsCode4.szTradeAir[0] = 1; tagRsCode4.szTradeAir[1] = 0; break; } memcpy(chBuffer4High, &tagRsCode4, sizeof(chBuffer4High)); memcpy(chBuffer4Low, ((char *)&tagRsCode4) + sizeof(chBuffer4High), sizeof(chBuffer4Low)); tagRequest.szRsCode[6] = Hex16(chBuffer4High) + '0'; tagRequest.szRsCode[7] = Hex16(chBuffer4Low) + '0'; // 算检验 BYTE btParityHigh = ( (nAddr >> 12) & 0x000F ) ^ ( (nAddr >> 4) & 0x000F ) ^ (Hex16(chBuffer1High)) ^ (Hex16(chBuffer2High)) ^ 0 ^ (Hex16(chBuffer3High)) ^ (Hex16(chBuffer4High) ); BYTE btParityLow =( (nAddr >> 8) & 0x000F ) ^ ( (nAddr) & 0x000F ) ^ (Hex16(chBuffer1Low)) ^ (Hex16(chBuffer2Low)) ^ 0 ^ (Hex16(chBuffer3Low)) ^ (Hex16(chBuffer4Low) ); tagRequest.szParity[0] = btParityHigh + '0'; tagRequest.szParity[1] = btParityLow + '0'; tagRequest.btEnd = 0x0D; if( WaitForSingleObject( m_hSemComm, 0 ) == WAIT_OBJECT_0 ) // 有信号才写串口 { ResetEvent( m_hSemComm ); int nResult = WriteMessage( (BYTE *)&tagRequest, nLen ); if( nResult == nLen ) { } else { SetEvent( m_hSemComm ); return EER_CODE_GREE_COM_WRITE_DATA; } } else { return ERR_CODE_GREE_COM_BUSY; } return 0; } int CProtocolModbus::ResponseWrStatus( int nAddr, int nWorkStatus, int nWorkMode, int nFanSpeed, int nPutWind, int nAirTrade, int nSleep, int nLight, int nTempSetPoint ) { RESPONSE_STRUCT structResponse; memset( &structResponse, 0, sizeof(RESPONSE_STRUCT) ); int nLen = sizeof(RESPONSE_STRUCT); char *pBuffer = new char[ nLen ]; memset(pBuffer, 0, nLen); int nProcessLen = 0; int nReadLen = 0; nReadLen = ReadMessage((BYTE *)pBuffer, nLen); if( nReadLen <= 0) { // 串口没有读到数据 TRACE("串口没有读到数据!\r\n"); SetEvent( m_hSemComm ); if( pBuffer != NULL) { delete[] pBuffer; pBuffer = NULL; } return ERR_CODE_GREE_COM_READ_NO_DATA; } else if( nReadLen < nLen ) { TRACE("长度没有收够,断续接收,止到收完为止!\r\n"); SetEvent( m_hSemComm ); if( pBuffer != NULL) { delete[] pBuffer; pBuffer = NULL; } return ERR_CODE_GREE_COM_FAULT; } // 判断校验 RESPONSE_STRUCT *pResponse = (RESPONSE_STRUCT *)pBuffer; // 算检验 int high = ( (pResponse->szAddr[0] - '0') ^ (pResponse->szAddr[2] - '0') ^ (pResponse->szRsCode[0] - '0') ^ (pResponse->szRsCode[2] - '0') ^ (pResponse->szRsCode[4] - '0') ^ (pResponse->szRsCode[6] - '0') ^ (pResponse->szEnvTemp[0] - '0') ^ (pResponse->szStatus1[0] - '0') ^ (pResponse->szStatus2[0] - '0') ^ (pResponse->szStatus3[0] - '0') ); int low = ( (pResponse->szAddr[1] - '0') ^ (pResponse->szAddr[3] - '0') ^ (pResponse->szRsCode[1] - '0') ^ (pResponse->szRsCode[3] - '0') ^ (pResponse->szRsCode[5] - '0') ^ (pResponse->szRsCode[7] - '0') ^ (pResponse->szEnvTemp[1] - '0') ^ (pResponse->szStatus1[1] - '0') ^ (pResponse->szStatus2[1] - '0') ^ (pResponse->szStatus3[1] - '0') ); if( !( ((byte)pBuffer[nLen - 2] == ByteToAscii(low) ) && ((byte)pBuffer[nLen - 3] == ByteToAscii(high) ) ) ) { TRACE("校验码失败!\r\n"); SetEvent( m_hSemComm ); if( pBuffer != NULL) { delete[] pBuffer; pBuffer = NULL; } return ERR_CODE_GREE_COM_LRC_LOST; } // 设置串口等待事件为有信号 SetEvent( m_hSemComm ); if( pBuffer != NULL) { delete[] pBuffer; pBuffer = NULL; } return 0; } int CProtocolModbus::RequestStatus(int nAddr) { int iLen = sizeof(REQUESTPARAM); REQUESTPARAM RequestPara; memset( &RequestPara, 0, iLen ); RequestPara.btStart = 0x07; RequestPara.szAddr[0] = ByteToAscii( (nAddr >> 12) & 0x000F ); RequestPara.szAddr[1] = ByteToAscii( (nAddr >> 8) & 0x000F ); RequestPara.szAddr[2] = ByteToAscii( (nAddr >> 4) & 0x000F ); RequestPara.szAddr[3] = ByteToAscii( nAddr & 0x000F ); for( int i = 0; i < 8; i++ ) { RequestPara.szRsCode[i] = ByteToAscii(0); } char chBuffer1High[4]; memset( chBuffer1High, 0, sizeof(chBuffer1High) ); char chBuffer1Low[4]; memset( chBuffer1Low, 0, sizeof(chBuffer1Low) ); RsCode1 tagRsCode1; memset(&tagRsCode1, 0, sizeof(RsCode1)); tagRsCode1.szStatus = 0; //这里为查询状态, 其它位无意义, 所以都置成0 memcpy(chBuffer1High, (char *)&tagRsCode1, sizeof(RsCode1) / 2); memcpy(chBuffer1Low, ((char *)&tagRsCode1) + sizeof(RsCode1) / 2, sizeof(RsCode1) / 2); RequestPara.szRsCode[0] = Hex16(chBuffer1High) + '0'; RequestPara.szRsCode[1] = Hex16(chBuffer1Low) + '0'; // 算检验 BYTE btParityHigh = ( (nAddr >> 12) & 0x000F ) ^ ( (nAddr >> 4) & 0x000F ) ^ (Hex16(chBuffer1High)); BYTE btParityLow =( (nAddr >> 8) & 0x000F ) ^ ( (nAddr) & 0x000F ) ^ (Hex16(chBuffer1Low)); RequestPara.szParity[0] = btParityHigh + '0'; RequestPara.szParity[1] = btParityLow + '0'; RequestPara.btEnd = 0x0D; if( WaitForSingleObject( m_hSemComm, 0 ) == WAIT_OBJECT_0 ) // 有信号才写串口 { ResetEvent( m_hSemComm ); int nResult = WriteMessage( (BYTE *)&RequestPara, iLen ); if( nResult == iLen ) { } else { SetEvent( m_hSemComm ); return EER_CODE_GREE_COM_WRITE_DATA; } } else { return ERR_CODE_GREE_COM_BUSY; } return 0; } int CProtocolModbus::ResponseStatus( int nAddr, int nDataLen, int nReadPos, char chMsg[80]) { #if 1 // 回应 //08 30 30 30 31 3C 39 30 36 30 30 34 32 32 31 36 .0001<9060042216 //34 32 3F 3C 30 32 36 0F 42?<026. // 08 30 30 30 31 3C 39 39 32 30 30 34 30 32 33 38 34 30 3D 3C 30 37 30 0F char szBuffer[256]; memset(szBuffer, 0, sizeof(szBuffer)); szBuffer[0] = 0x08; szBuffer[1] = 0x30; szBuffer[2] = 0x30; szBuffer[3] = 0x30; szBuffer[4] = 0x31; szBuffer[5] = 0x3C; szBuffer[6] = 0x39; szBuffer[7] = 0x39; szBuffer[8] = 0x32; szBuffer[9] = 0x30; szBuffer[10] = 0x30; szBuffer[11] = 0x34; szBuffer[12] = 0x30; szBuffer[13] = 0x32; szBuffer[14] = 0x33; szBuffer[15] = 0x38; szBuffer[16] = 0x34; szBuffer[17] = 0x30; szBuffer[18] = 0x3D; szBuffer[19] = 0x3C; szBuffer[20] = 0x30; szBuffer[21] = 0x37; szBuffer[22] = 0x30; szBuffer[23] = 0x0F; int nLen = 24; RESPONSE_STRUCT *pResponse = (RESPONSE_STRUCT *)szBuffer; // 算检验 int high = ( (pResponse->szAddr[0] - '0') ^ (pResponse->szAddr[2] - '0') ^ (pResponse->szRsCode[0] - '0') ^ (pResponse->szRsCode[2] - '0') ^ (pResponse->szRsCode[4] - '0') ^ (pResponse->szRsCode[6] - '0') ^ (pResponse->szEnvTemp[0] - '0') ^ (pResponse->szStatus1[0] - '0') ^ (pResponse->szStatus2[0] - '0') ^ (pResponse->szStatus3[0] - '0') ); int low = ( (pResponse->szAddr[1] - '0') ^ (pResponse->szAddr[3] - '0') ^ (pResponse->szRsCode[1] - '0') ^ (pResponse->szRsCode[3] - '0') ^ (pResponse->szRsCode[5] - '0') ^ (pResponse->szRsCode[7] - '0') ^ (pResponse->szEnvTemp[1] - '0') ^ (pResponse->szStatus1[1] - '0') ^ (pResponse->szStatus2[1] - '0') ^ (pResponse->szStatus3[1] - '0') ); if( !( ((byte)szBuffer[nLen - 2] == ByteToAscii(low) ) && ((byte)szBuffer[nLen - 3] == ByteToAscii(high) ) ) ) { return ERR_CODE_GREE_COM_LRC_LOST; } EnterCriticalSection( &m_csReadFinished ); //memcpy( &m_structResponse, pBuffer, sizeof(RESPONSE_STRUCT) ); for( int i = 0; i < nDataLen; i++ ) { chMsg[i] = szBuffer[nReadPos + i]; } LeaveCriticalSection(&m_csReadFinished); // 设置串口等待事件为有信号 SetEvent( m_hSemComm ); #else RESPONSE_STRUCT structResponse; memset( &structResponse, 0, sizeof(RESPONSE_STRUCT) ); if (nDataLen <= 0) { TRACE("变量长度小于等于0,为非法变量"); return ERR_CODE_GREE_COM_VARLEN; } int nLen = sizeof(RESPONSE_STRUCT);// - sizeof(structResponse.StrRtnMsg) + nDataLen; char *pBuffer = new char[ nLen ]; memset(pBuffer, 0, nLen); int nProcessLen = 0; int nReadLen = 0; nReadLen = ReadMessage((BYTE *)pBuffer, nLen); if( nReadLen <= 0) { // 串口没有读到数据 TRACE("串口没有读到数据!\r\n"); SetEvent( m_hSemComm ); if( pBuffer != NULL) { delete[] pBuffer; pBuffer = NULL; } return ERR_CODE_GREE_COM_READ_NO_DATA; } else if( nReadLen < nLen ) { TRACE("长度没有收够,断续接收,止到收完为止!\r\n"); SetEvent( m_hSemComm ); if( pBuffer != NULL) { delete[] pBuffer; pBuffer = NULL; } return ERR_CODE_GREE_COM_FAULT; } else if( nReadLen > nLen ) { // 完全代码,不一定能执行到 TRACE("接收的长度超时所需的长度,认为是非法包,扔掉\r\n"); SetEvent( m_hSemComm ); if( pBuffer != NULL) { delete[] pBuffer; pBuffer = NULL; } return ERR_CODE_GREE_COM_READ_LEN_OVER; } // 判断校验 RESPONSE_STRUCT *pResponse = (RESPONSE_STRUCT *)pBuffer; // 算检验 int high = ( (pResponse->szAddr[0] - '0') ^ (pResponse->szAddr[2] - '0') ^ (pResponse->szRsCode[0] - '0') ^ (pResponse->szRsCode[2] - '0') ^ (pResponse->szRsCode[4] - '0') ^ (pResponse->szRsCode[6] - '0') ^ (pResponse->szEnvTemp[0] - '0') ^ (pResponse->szStatus1[0] - '0') ^ (pResponse->szStatus2[0] - '0') ^ (pResponse->szStatus3[0] - '0') ); int low = ( (pResponse->szAddr[1] - '0') ^ (pResponse->szAddr[3] - '0') ^ (pResponse->szRsCode[1] - '0') ^ (pResponse->szRsCode[3] - '0') ^ (pResponse->szRsCode[5] - '0') ^ (pResponse->szRsCode[7] - '0') ^ (pResponse->szEnvTemp[1] - '0') ^ (pResponse->szStatus1[1] - '0') ^ (pResponse->szStatus2[1] - '0') ^ (pResponse->szStatus3[1] - '0') ); if( !( ((byte)pBuffer[nLen - 2] == ByteToAscii(low) ) && ((byte)pBuffer[nLen - 3] == ByteToAscii(high) ) ) ) { TRACE("校验码失败!\r\n"); SetEvent( m_hSemComm ); if( pBuffer != NULL) { delete[] pBuffer; pBuffer = NULL; } return ERR_CODE_GREE_COM_LRC_LOST; } EnterCriticalSection( &m_csReadFinished ); //memcpy( &m_structResponse, pBuffer, sizeof(RESPONSE_STRUCT) ); for( int i = 0; i < nDataLen; i++ ) { chMsg[i] = pBuffer[nReadPos + i]; } LeaveCriticalSection(&m_csReadFinished); // 设置串口等待事件为有信号 SetEvent( m_hSemComm ); if( pBuffer != NULL) { delete[] pBuffer; pBuffer = NULL; } #endif return 0; } UINT CProtocolModbus::GetCRC(BYTE *pBuf, int len) { unsigned int Genpoly=0xA001; unsigned int CRC=0xFFFF; unsigned int index; while(len--) { CRC=CRC^(unsigned int)*pBuf++; for(index=0;index<8;index++) { if((CRC & 0x0001)==1) CRC=(CRC>>1)^Genpoly; else (CRC=CRC>>1); } } return(CRC); } BOOL CProtocolModbus::InitParam(PPORTPARAM pPortParam, CCommAsyn *pComm) { int addr=pPortParam->StartAddr; m_pComm=pComm; return TRUE; } void strReverse( char *str ) { int l = strlen(str); for( int i = 0; i < l; i++ ) { for(int i = 0; i < l; i++) { if( str[i] >= 'A' && str[i] <= 'Z' ) { str[i] += 32; } else if(str[i] >= 'a' && str[i] <= 'z') { str[i] -= 32; } } } } char lowercase2uppercase(BYTE btSrc) { if( btSrc >= 'a' && btSrc <= 'z' ) { return btSrc - 'a' + 'A'; } return btSrc; } char ByteToAscii(BYTE btSrc) { char chDest; if( btSrc < 10 ) { chDest = (char)(btSrc % 10 + '0'); chDest = lowercase2uppercase(chDest); return chDest; } else { chDest = ByteToAscii( btSrc / 10 ) + (char)( btSrc % 10 + '0' ); chDest = lowercase2uppercase(chDest); return chDest; } } WORD AsciiToBYTE(BYTE btSrc) { WORD chDest = (WORD)btSrc; if ((btSrc >= 'A')&&(btSrc <= 'F')) { chDest = chDest - 'A' + 10; } else if ((btSrc >= 'a')&&(btSrc <= 'f')) { chDest = chDest - 'a' + 10; } else if ((btSrc >= '0')&&(btSrc <= '9')) { chDest -= '0'; } return chDest; }