// ProtocolPMC916.cpp: implementation of the CProtocolModbus class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ProtocolModbus.h" #include "winsock2.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CProtocolModbus::CProtocolModbus() : CProtocol() { InitializeCriticalSection( &m_csReadFinished ); InitializeCriticalSection( &m_csWrFinished ); MTVERIFY( m_hSemComm = CreateEvent( NULL, TRUE, TRUE, "DLL_UpsParaDigmComm" ) ); } CProtocolModbus::~CProtocolModbus() { DeleteCriticalSection( &m_csReadFinished ); DeleteCriticalSection( &m_csWrFinished ); MTVERIFY( CloseHandle( m_hSemComm ) ); } int CProtocolModbus::WorkMain( int nAddr, //地址 int nVer, //版本号 int nCid1, //控制标识码 int nCid2, //命令信息 WORD wLenId, //INFO字节长度 int nCmdID, //命令ID int nDataLen, //请求数据长度 int nCmdPos, //变量索引 int nCmdLen, //变量长度 char chMsg[80], //读到的变量值 char *byDataFlag) //保留未用 { if(!m_pComm) return ERR_CODE_DAIKIN_COM_FAULT; // 串口通信故障 int nRet; #if 1 nRet = RequestStatus(nAddr, nVer, nCid1, nCid2, wLenId, nCmdID, nDataLen, nCmdPos, nCmdLen, chMsg, byDataFlag); if( nRet != 0 ) { return nRet; // 串口忙 } nRet = ResponseStatus(nDataLen, nCmdPos, nCmdLen,chMsg, byDataFlag); #else if( nCid2 == 0x44 || nCid2 == 0x42 || nCid2 == 0x43 ) { nRet = ResponseStatus(nDataLen, nCmdPos, nCmdLen,chMsg, byDataFlag); } else { nRet = -1; } #endif return nRet; } int CProtocolModbus::WriteCommand( int nCommPort, //端口 int nAddr, //地址 int nVer, //版本号 int nCid1, //控制标识码 int nCid2, //命令信息 WORD wLenId, //INFO字节长度 int nCmdType, //命令类型 int nSetValue) //设定值 { int iResult = 0; if(!m_pComm) return ERR_CODE_DAIKIN_COM_FAULT; iResult = RequestSetParam( nCommPort, nAddr, nVer, nCid1, nCid2, wLenId, nCmdType, nSetValue); if (iResult == 0) { return ResponseSetParam( nCommPort, nAddr, nVer, nCid1, nCid2, wLenId, nCmdType, nSetValue); } else { return iResult; } } int CProtocolModbus::WriteCommand( int nCommPort, //端口 int nAddr, //地址 int nSetType, //设定类型 int nSetIndex, //设定值索引,只针对特殊变量(例如:空调制冷、制热温度) int nSetValue) //设定值 { int iResult = 0; if(!m_pComm) return ERR_CODE_DAIKIN_COM_FAULT; iResult = RequestRemoteCtrl( nCommPort, nAddr, nSetType, nSetIndex, nSetValue); if (iResult == 0) { return ResponseRemoteCtrl( nCommPort, nAddr, nSetType, nSetIndex, nSetValue); } else { return iResult; } } int CProtocolModbus::RequestSetParam( int nCommPort, //端口 int nAddr, //地址 int nVer, //版本号 int nCid1, //控制标识码 int nCid2, //命令信息 WORD wLenId, //INFO字节长度 int nCmdType, //命令类型 int nSetValue) //设定值 { int nLen = sizeof(CHILD); char chLength[4] = {0}; char chChkSum[5] = {0}; CHILD tagRequestChild; memset( &tagRequestChild, 0, nLen ); //起始位 tagRequestChild.bySoi = 0x7E; //设备地址描述 tagRequestChild.byAdr[0] = ByteToAscii((nAddr>>4) & 0x0f); tagRequestChild.byAdr[1] = ByteToAscii(nAddr & 0x0f); //通讯协议版本 tagRequestChild.byVer[0] = ByteToAscii((nVer>>4) & 0x0f); tagRequestChild.byVer[1] = ByteToAscii(nVer & 0x0f); //Cid1 tagRequestChild.byCid1[0] = ByteToAscii((nCid1>>4) & 0x0f); tagRequestChild.byCid1[1] = ByteToAscii(nCid1 & 0x0f); //Cid2 tagRequestChild.byCid2[0] = ByteToAscii((nCid2 >> 4) & 0x0f); tagRequestChild.byCid2[1] = ByteToAscii(nCid2 & 0x0f); GetDataLength(wLenId, chLength);//取数据长度 tagRequestChild.byLength[0] = ByteToAscii(chLength[0]); tagRequestChild.byLength[1] = chLength[1]; tagRequestChild.byLength[2] = chLength[2]; tagRequestChild.byLength[3] = chLength[3]; BYTE *pDataBuf = NULL; int nWriteLen = 0; REQUESTSETPARAM tagRequestSetParam; int nSetParamLen = sizeof(REQUESTSETPARAM); memset( &tagRequestSetParam, 0, nSetParamLen); memcpy( &tagRequestSetParam.RequestChild, &tagRequestChild, nLen ); //设置命令 tagRequestSetParam.szCmdType[0] = ByteToAscii((nCmdType >> 4) & 0x0f); tagRequestSetParam.szCmdType[1] = ByteToAscii(nCmdType & 0x0f); //设置内容 tagRequestSetParam.szCmdInfo[0] = ByteToAscii( (nSetValue >> 12) & 0x000f ); tagRequestSetParam.szCmdInfo[1] = ByteToAscii( (nSetValue >> 8) & 0x000f ); tagRequestSetParam.szCmdInfo[2] = ByteToAscii( (nSetValue >> 4) & 0x000f ); tagRequestSetParam.szCmdInfo[3] = ByteToAscii( nSetValue & 0x000f ); nWriteLen = nSetParamLen - sizeof(tagRequestSetParam.byCheckSum) - sizeof(tagRequestSetParam.byEoi); pDataBuf = new BYTE[ nWriteLen ]; memset( pDataBuf, 0, nWriteLen ); memcpy( pDataBuf, &tagRequestSetParam, nWriteLen ); //校验码 GetCheckSum( (char *)pDataBuf + 1, chChkSum, nWriteLen - 1 ); tagRequestSetParam.byCheckSum[0] = chChkSum[0]; tagRequestSetParam.byCheckSum[1] = chChkSum[1]; tagRequestSetParam.byCheckSum[2] = chChkSum[2]; tagRequestSetParam.byCheckSum[3] = chChkSum[3]; tagRequestSetParam.byEoi = 0x0D; if( WaitForSingleObject( m_hSemComm, 0 ) == WAIT_OBJECT_0 ) // 有信号才写串口 { ResetEvent( m_hSemComm ); int nResult = WriteMessage( (BYTE *)&tagRequestSetParam, nLen ); if( nResult == nLen ) { } else { delete []pDataBuf; SetEvent( m_hSemComm ); return EER_CODE_DAIKIN_COM_WRITE_DATA; } } else { delete []pDataBuf; return ERR_CODE_DAIKIN_COM_BUSY; } if( pDataBuf ) { delete[] pDataBuf; pDataBuf = NULL; } return 0; } int CProtocolModbus::ResponseSetParam( int nCommPort, //端口 int nAddr, //地址 int nVer, //版本号 int nCid1, //控制标识码 int nCid2, //命令信息 WORD wLenId, //INFO字节长度 int nCmdType, //命令类型 int nSetValue) //设定值 { RESPONSE_STRUCT structResponse; memset( &structResponse, 0, sizeof(RESPONSE_STRUCT) ); int nLen = sizeof(RESPONSE_STRUCT) - sizeof(structResponse.byRtnMsg); 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_DAIKIN_COM_READ_NO_DATA; } else if( nReadLen < nLen ) { TRACE("长度没有收够,断续接收,止到收完为止!\r\n"); #if DEBUG_PROTOCOL SetEvent( m_hSemComm ); if( pBuffer ) { delete[] pBuffer; pBuffer = NULL; } return ERR_CODE_DAIKIN_COM_FAULT; #else nProcessLen += nReadLen; nReadLen = ReadMessage( (BYTE *)(pBuffer + nProcessLen), nLen - nProcessLen ); while( nReadLen != nLen - nProcessLen ) { if( nReadLen == 0 ) { SetEvent( m_hSemComm ); if( pBuffer ) { delete[] pBuffer; pBuffer = NULL; } return ERR_CODE_UPS_PARADIGM_COM_READ_NO_DATA; // 还是没有收到数据,直接返回 } nProcessLen += nReadLen; nReadLen = ReadMessage( (BYTE *)(pBuffer + nProcessLen), nLen - nProcessLen); } if( nReadLen == nLen ) { //goto NormalProcess; if( pBuffer != NULL) { delete[] pBuffer; pBuffer = NULL; } return ERR_CODE_UPS_PARADIGM_COM_FAULT; } #endif } else if( nReadLen > nLen ) { // 完全代码,不一定能执行到 TRACE("接收的长度超时所需的长度,认为是非法包,扔掉\r\n"); SetEvent( m_hSemComm ); if( pBuffer != NULL) { delete[] pBuffer; pBuffer = NULL; } return ERR_CODE_DAIKIN_COM_READ_LEN_OVER; } // 判断校验 char chChkSum[5] = {0}; BYTE chTmpChkSum[4] = {0}; GetCheckSum(pBuffer + 1, chChkSum, nLen - sizeof(structResponse.byCheckSum) - 2 ); chTmpChkSum[0] = chChkSum[0]; chTmpChkSum[1] = chChkSum[1]; chTmpChkSum[2] = chChkSum[2]; chTmpChkSum[3] = chChkSum[3]; if (!((chTmpChkSum[0] ==(byte)pBuffer[nLen - 4]) && (chTmpChkSum[1] ==(byte)pBuffer[nLen - 3]) && (chTmpChkSum[2] ==(byte)pBuffer[nLen - 2]) && (chTmpChkSum[3] ==(byte)pBuffer[nLen - 1]))) { TRACE("校验失败!\r\n"); SetEvent( m_hSemComm ); if( pBuffer != NULL) { delete[] pBuffer; pBuffer = NULL; } return ERR_CODE_DAIKIN_COM_LRC_LOST; } // 设置串口等待事件为有信号 SetEvent( m_hSemComm ); if( pBuffer != NULL) { delete[] pBuffer; pBuffer = NULL; } return 0; } int CProtocolModbus::RequestRemoteCtrl( int nCommPort, //端口 int nAddr, //地址 int nSetType, //设定类型 int nSetIndex, //设定值索引,只针对特殊变量(例如:空调制冷、制热温度) int nSetValue) //设定值 { int nLen = sizeof(CHILD); char chLength[4] = {0}; char chChkSum[5] = {0}; CHILD tagRequestChild; int nCid1 = 0x60; int nCid2 = 0x45; memset( &tagRequestChild, 0, nLen ); //起始位 tagRequestChild.bySoi = 0x7E; //设备地址描述 tagRequestChild.byAdr[0] = ByteToAscii((nAddr>>4) & 0x0f); tagRequestChild.byAdr[1] = ByteToAscii(nAddr & 0x0f); //通讯协议版本 tagRequestChild.byVer[0] = '2'; tagRequestChild.byVer[1] = '0'; //Cid1 tagRequestChild.byCid1[0] = ByteToAscii((nCid1>>4) & 0x0f); tagRequestChild.byCid1[1] = ByteToAscii(nCid1 & 0x0f); //Cid2 tagRequestChild.byCid2[0] = ByteToAscii((nCid2 >> 4) & 0x0f); tagRequestChild.byCid2[1] = ByteToAscii(nCid2 & 0x0f); //GetDataLength(5, chLength);//取数据长度 tagRequestChild.byLength[0] = 'E'; tagRequestChild.byLength[1] = '0'; tagRequestChild.byLength[2] = '0'; tagRequestChild.byLength[3] = '2'; BYTE *pDataBuf = NULL; int nWriteLen = 0; REQUEST_CTRL tagRequestCtrl; int nRemoteCtrlLen = sizeof(REQUEST_CTRL); memset( &tagRequestCtrl, 0, nRemoteCtrlLen); memcpy( &tagRequestCtrl.RequestChild, &tagRequestChild, nLen ); //设置命令 tagRequestCtrl.szCmdType[0] = ByteToAscii((nSetValue >> 4) & 0x0f); tagRequestCtrl.szCmdType[1] = ByteToAscii(nSetValue & 0x0f);; nWriteLen = nRemoteCtrlLen - sizeof(tagRequestCtrl.byCheckSum) - sizeof(tagRequestCtrl.byEoi); pDataBuf = new BYTE[ nWriteLen ]; memset( pDataBuf, 0, nWriteLen ); memcpy( pDataBuf, &tagRequestCtrl, nWriteLen ); //校验码 GetCheckSum( (char *)pDataBuf + 1, chChkSum, nWriteLen - 1 ); tagRequestCtrl.byCheckSum[0] = chChkSum[0]; tagRequestCtrl.byCheckSum[1] = chChkSum[1]; tagRequestCtrl.byCheckSum[2] = chChkSum[2]; tagRequestCtrl.byCheckSum[3] = chChkSum[3]; tagRequestCtrl.byEoi = 0x0D; if( WaitForSingleObject( m_hSemComm, 0 ) == WAIT_OBJECT_0 ) // 有信号才写串口 { ResetEvent( m_hSemComm ); int nResult = WriteMessage( (BYTE *)&tagRequestCtrl, nRemoteCtrlLen ); if( nResult == nRemoteCtrlLen ) { } else { delete []pDataBuf; SetEvent( m_hSemComm ); return EER_CODE_DAIKIN_COM_WRITE_DATA; } } else { delete []pDataBuf; return ERR_CODE_DAIKIN_COM_BUSY; } if( pDataBuf ) { delete[] pDataBuf; pDataBuf = NULL; } return 0; } int CProtocolModbus::ResponseRemoteCtrl( int nCommPort, //端口 int nAddr, //地址 int nSetType, //设定类型 int nSetIndex, //设定值索引,只针对特殊变量(例如:空调制冷、制热温度) int nSetValue) //设定值 { RESPONSE_STRUCT structResponse; memset( &structResponse, 0, sizeof(RESPONSE_STRUCT) ); int nLen = sizeof(RESPONSE_STRUCT) - sizeof(structResponse.byRtnMsg); 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_DAIKIN_COM_READ_NO_DATA; } else if( nReadLen < nLen ) { TRACE("长度没有收够,断续接收,止到收完为止!\r\n"); SetEvent( m_hSemComm ); if( pBuffer ) { delete[] pBuffer; pBuffer = NULL; } return ERR_CODE_DAIKIN_COM_FAULT; } else if( nReadLen > nLen ) { // 完全代码,不一定能执行到 TRACE("接收的长度超时所需的长度,认为是非法包,扔掉\r\n"); SetEvent( m_hSemComm ); if( pBuffer != NULL) { delete[] pBuffer; pBuffer = NULL; } return ERR_CODE_DAIKIN_COM_READ_LEN_OVER; } // 判断校验 char chChkSum[5] = {0}; BYTE chTmpChkSum[4] = {0}; GetCheckSum(pBuffer + 1, chChkSum, nLen - sizeof(structResponse.byCheckSum) - 2 ); chTmpChkSum[0] = chChkSum[0]; chTmpChkSum[1] = chChkSum[1]; chTmpChkSum[2] = chChkSum[2]; chTmpChkSum[3] = chChkSum[3]; if (!((chTmpChkSum[0] ==(byte)pBuffer[nLen - 5]) && (chTmpChkSum[1] ==(byte)pBuffer[nLen - 4]) && (chTmpChkSum[2] ==(byte)pBuffer[nLen - 3]) && (chTmpChkSum[3] ==(byte)pBuffer[nLen - 2]))) { TRACE("校验失败!\r\n"); SetEvent( m_hSemComm ); if( pBuffer != NULL) { delete[] pBuffer; pBuffer = NULL; } return ERR_CODE_DAIKIN_COM_LRC_LOST; } // 设置串口等待事件为有信号 SetEvent( m_hSemComm ); if( pBuffer != NULL) { delete[] pBuffer; pBuffer = NULL; } return 0; } int CProtocolModbus::ResponseStatus( int nDataLen, int iCmdPos, int iCmdLen, char chMsg[80], char *byDataFlag) { #if 1 RESPONSE_STRUCT structResponse; memset( &structResponse, 0, sizeof(RESPONSE_STRUCT) ); if (nDataLen <= 0) { TRACE("变量长度小于等于0,为非法变量"); return ERR_CODE_DAIKIN_COM_VARLEN; } int nLen = sizeof(RESPONSE_STRUCT) - sizeof(structResponse.byRtnMsg) + 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_DAIKIN_COM_READ_NO_DATA; } else if( nReadLen < nLen ) { TRACE("长度没有收够,断续接收,止到收完为止!\r\n"); SetEvent( m_hSemComm ); if( pBuffer ) { delete[] pBuffer; pBuffer = NULL; } return ERR_CODE_DAIKIN_COM_FAULT; } else if( nReadLen > nLen ) { // 完全代码,不一定能执行到 TRACE("接收的长度超时所需的长度,认为是非法包,扔掉\r\n"); SetEvent( m_hSemComm ); if( pBuffer != NULL) { delete[] pBuffer; pBuffer = NULL; } return ERR_CODE_DAIKIN_COM_READ_LEN_OVER; } #else //7E 32 30 30 31 36 30 30 30 39 30 33 34 30 30 20 ~20016000903400 //20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 //20 20 20 20 20 20 20 20 20 20 20 30 38 44 31 20 08D1 //20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 30 0 //30 46 36 38 41 0D 0F68A. RESPONSE_STRUCT structResponse; memset( &structResponse, 0, sizeof(RESPONSE_STRUCT) ); #if 0 int nLen = 70; char *pBuffer = new char[ nLen ]; memset(pBuffer, 0, nLen); pBuffer[0] = 0x7E; pBuffer[1] = 0x32; pBuffer[2] = 0x30; pBuffer[3] = 0x30; pBuffer[4] = 0x31; pBuffer[5] = 0x36; pBuffer[6] = 0x30; pBuffer[7] = 0x30; pBuffer[8] = 0x30; pBuffer[9] = 0x39; pBuffer[10] = 0x30; pBuffer[11] = 0x33; pBuffer[12] = 0x34; pBuffer[13] = 0x30; pBuffer[14] = 0x30; pBuffer[15] = 0x20; pBuffer[16] = 0x20; pBuffer[17] = 0x20; pBuffer[18] = 0x20; pBuffer[19] = 0x20; pBuffer[20] = 0x20; pBuffer[21] = 0x20; pBuffer[22] = 0x20; pBuffer[23] = 0x20; pBuffer[24] = 0x20; pBuffer[25] = 0x20; pBuffer[26] = 0x20; pBuffer[27] = 0x20; pBuffer[28] = 0x20; pBuffer[29] = 0x20; pBuffer[30] = 0x20; pBuffer[31] = 0x20; pBuffer[32] = 0x20; pBuffer[33] = 0x20; pBuffer[34] = 0x20; pBuffer[35] = 0x20; pBuffer[36] = 0x20; pBuffer[37] = 0x20; pBuffer[38] = 0x20; pBuffer[39] = 0x20; pBuffer[40] = 0x20; pBuffer[41] = 0x20; pBuffer[42] = 0x20; pBuffer[43] = 0x30; pBuffer[44] = 0x38; pBuffer[45] = 0x44; pBuffer[46] = 0x31; pBuffer[47] = 0x20; pBuffer[48] = 0x20; pBuffer[49] = 0x20; pBuffer[50] = 0x20; pBuffer[51] = 0x20; pBuffer[52] = 0x20; pBuffer[53] = 0x20; pBuffer[54] = 0x20; pBuffer[55] = 0x20; pBuffer[56] = 0x20; pBuffer[57] = 0x20; pBuffer[58] = 0x20; pBuffer[59] = 0x20; pBuffer[60] = 0x20; pBuffer[61] = 0x20; pBuffer[62] = 0x20; pBuffer[63] = 0x30; pBuffer[64] = 0x30; pBuffer[65] = 0x46; pBuffer[66] = 0x36; pBuffer[67] = 0x38; pBuffer[68] = 0x41; pBuffer[69] = 0x0D; #endif //7E 32 30 30 32 36 30 34 33 30 30 30 30 46 44 41 //46 0D int nLen = 18; char *pBuffer = new char[ nLen ]; memset(pBuffer, 0, nLen); pBuffer[0] = 0x7E; pBuffer[1] = 0x32; pBuffer[2] = 0x30; pBuffer[3] = 0x30; pBuffer[4] = 0x32; pBuffer[5] = 0x36; pBuffer[6] = 0x30; pBuffer[7] = 0x34; pBuffer[8] = 0x33; pBuffer[9] = 0x30; pBuffer[10] = 0x30; pBuffer[11] = 0x30; pBuffer[12] = 0x30; pBuffer[13] = 0x46; pBuffer[14] = 0x44; pBuffer[15] = 0x41; pBuffer[16] = 0x46; pBuffer[17] = 0x0D; #endif // 判断校验 char chChkSum[5] = {0}; BYTE chTmpChkSum[4] = {0}; GetCheckSum(pBuffer + 1, chChkSum, nLen - sizeof(structResponse.byCheckSum) - 2 ); chTmpChkSum[0] = chChkSum[0]; chTmpChkSum[1] = chChkSum[1]; chTmpChkSum[2] = chChkSum[2]; chTmpChkSum[3] = chChkSum[3]; if (!((chTmpChkSum[0] ==(byte)pBuffer[nLen - 5]) && (chTmpChkSum[1] ==(byte)pBuffer[nLen - 4]) && (chTmpChkSum[2] ==(byte)pBuffer[nLen - 3]) && (chTmpChkSum[3] ==(byte)pBuffer[nLen - 2]))) { TRACE("校验失败!\r\n"); SetEvent( m_hSemComm ); if( pBuffer != NULL) { delete[] pBuffer; pBuffer = NULL; } return ERR_CODE_DAIKIN_COM_LRC_LOST; } //取变量数据 EnterCriticalSection( &m_csWrFinished ); memcpy( &m_structResponse.RequestChild, pBuffer, sizeof(CHILD) ); byDataFlag[0] = pBuffer[sizeof(CHILD)]; for( int i = 0; i < iCmdLen; i++ ) { //if( iCmdPos > nLen - sizeof(CHILD) ) break; chMsg[i] = pBuffer[sizeof(CHILD) + iCmdPos + i]; } LeaveCriticalSection(&m_csWrFinished); // 设置串口等待事件为有信号 SetEvent( m_hSemComm ); if( pBuffer != NULL) { delete[] pBuffer; pBuffer = NULL; } return 0; } int CProtocolModbus::RequestStatus ( int nAddr, //地址 int nVer, //版本号 int nCid1, //控制标识码 int nCid2, //命令信息 WORD wLenId, //INFO字节长度 int nCmdID, //命令ID int nDataLen, //请求数据长度 int nCmdPos, //变量索引 int nCmdLen, //变量长度 char chMsg[80], //读到的变量值 char *byDataFlag) { int iLen = sizeof(REQUESTPARAM); char chLength[4] = {0}; char chChkSum[5] = {0}; REQUESTPARAM RequestPara; memset( &RequestPara, 0, iLen ); //起始位 RequestPara.RequestChild.bySoi = 0x7E; //通讯协议版本 itoa(nVer, (char *)RequestPara.RequestChild.byVer, 10); //设备地址描述 itoa(nAddr, (char *)RequestPara.RequestChild.byAdr, 10); RequestPara.RequestChild.byAdr[0] = ByteToAscii((nAddr>>4) & 0x0f); RequestPara.RequestChild.byAdr[1] = ByteToAscii(nAddr & 0x0f); //Cid1 RequestPara.RequestChild.byCid1[0] = ByteToAscii((nCid1>>4) & 0x0f); RequestPara.RequestChild.byCid1[1] = ByteToAscii(nCid1 & 0x0f); //Cid2 RequestPara.RequestChild.byCid2[0] = ByteToAscii((nCid2 >> 4) & 0x0f); RequestPara.RequestChild.byCid2[1] = ByteToAscii(nCid2 & 0x0f); GetDataLength(wLenId, chLength);//取数据长度 RequestPara.RequestChild.byLength[0] = ByteToAscii(chLength[0]); RequestPara.RequestChild.byLength[1] = chLength[1]; RequestPara.RequestChild.byLength[2] = chLength[2]; RequestPara.RequestChild.byLength[3] = chLength[3]; //校验码 BYTE *pDataBuf = new BYTE[ iLen - sizeof(RequestPara.byCheckSum) - 1 ]; memset(pDataBuf, 0, iLen - sizeof(RequestPara.byCheckSum) - 1 ); memcpy(pDataBuf, &RequestPara, iLen - sizeof(RequestPara.byCheckSum) - 1 ); GetCheckSum((char *)pDataBuf + 1, chChkSum, iLen - sizeof(RequestPara.byCheckSum) - 2 ); RequestPara.byCheckSum[0] = chChkSum[0]; RequestPara.byCheckSum[1] = chChkSum[1]; RequestPara.byCheckSum[2] = chChkSum[2]; RequestPara.byCheckSum[3] = chChkSum[3]; //结束符 RequestPara.byEoi = 0x0D; if( WaitForSingleObject( m_hSemComm, 0 ) == WAIT_OBJECT_0 ) // 有信号才写串口 { ResetEvent( m_hSemComm ); int nResult = WriteMessage( (BYTE *)&RequestPara, iLen ); if( nResult == iLen ) { } else { delete []pDataBuf; SetEvent( m_hSemComm ); return EER_CODE_DAIKIN_COM_WRITE_DATA; } } else { delete []pDataBuf; return ERR_CODE_DAIKIN_COM_BUSY; } delete[]pDataBuf; return 0; } UINT CProtocolModbus::GetCheckSum(char *pBuf, char chDest[5], int len) { WORD iSum = 0; //unsigned char chCompliment[2] = {0}; for(int i=0; iStartAddr; m_pComm=pComm; return TRUE; } int DigitToBinary(WORD wdSource, char* pDes, int iBit) { char pTmpBuf[16] = {0}; char chBuffer[16] = {0}; //wdSource =htonl(wdSource); itoa(wdSource, pTmpBuf, 2); int iLen = (int)strlen(pTmpBuf) - 1; char chValue[16] = {0}; strcpy(chValue, pTmpBuf); for (int i =0; i<=iLen; i++) { pTmpBuf[i] = chValue[iLen - i]; } for (int k = 0; k= '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; } /* Convert a binary data buffer to a hex string str: output (a string like “20ef9a“) bin: input (a data buffer) binlen: input (the length of the data buffer) */ void bin2str(char *str, const unsigned char *bin, int binlen) { int i; for(i=0; i> 4); str[2*i] = (str[2*i] > 9) ? (str[2*i] + 'A' - 10) : (str[2*i] + '0'); str[2*i+1] = (bin[i] & 0x0F); str[2*i+1] = (str[2*i+1] > 9) ? (str[2*i+1] + 'A' - 10) : (str[2*i+1] + '0'); } str[2*i] = '\0'; } char CProtocolModbus::GetLCheckSum(char *pBuf, int len) { //WORD iSum = 0; char chCompliment = 0; //unsigned char chCompliment[2] = {0}; for(int i=0; i>(sizeof(unsigned int)>>1)) <<(sizeof(unsigned int)>>1))); if(dwp=(char*)dwpend) b^=*pBuf--; return b; #endif }