ProtocolModbus.cpp 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150
  1. // ProtocolPMC916.cpp: implementation of the CProtocolModbus class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "ProtocolModbus.h"
  6. #include "winsock2.h"
  7. #ifdef _DEBUG
  8. #undef THIS_FILE
  9. static char THIS_FILE[]=__FILE__;
  10. #define new DEBUG_NEW
  11. #endif
  12. //////////////////////////////////////////////////////////////////////
  13. // Construction/Destruction
  14. //////////////////////////////////////////////////////////////////////
  15. CProtocolModbus::CProtocolModbus() : CProtocol()
  16. {
  17. InitializeCriticalSection( &m_csReadFinished );
  18. InitializeCriticalSection( &m_csWrFinished );
  19. MTVERIFY( m_hSemComm = CreateEvent( NULL, TRUE, TRUE, "DLL_UpsParaDigmComm" ) );
  20. }
  21. CProtocolModbus::~CProtocolModbus()
  22. {
  23. DeleteCriticalSection( &m_csReadFinished );
  24. DeleteCriticalSection( &m_csWrFinished );
  25. MTVERIFY( CloseHandle( m_hSemComm ) );
  26. }
  27. int CProtocolModbus::WorkMain(
  28. int nAddr, //地址
  29. int nVer, //版本号
  30. int nCid1, //控制标识码
  31. int nCid2, //命令信息
  32. WORD wLenId, //INFO字节长度
  33. int nCmdID, //命令ID
  34. int nDataLen, //请求数据长度
  35. int nCmdPos, //变量索引
  36. int nCmdLen, //变量长度
  37. char chMsg[80], //读到的变量值
  38. char *byDataFlag) //保留未用
  39. {
  40. if(!m_pComm)
  41. return ERR_CODE_DAIKIN_COM_FAULT; // 串口通信故障
  42. int nRet;
  43. #if 1
  44. nRet = RequestStatus(nAddr,
  45. nVer,
  46. nCid1,
  47. nCid2,
  48. wLenId,
  49. nCmdID,
  50. nDataLen,
  51. nCmdPos,
  52. nCmdLen,
  53. chMsg,
  54. byDataFlag);
  55. if( nRet != 0 )
  56. {
  57. return nRet; // 串口忙
  58. }
  59. nRet = ResponseStatus(nDataLen, nCmdPos, nCmdLen,chMsg, byDataFlag);
  60. #else
  61. if( nCid2 == 0x44 || nCid2 == 0x42 || nCid2 == 0x43 )
  62. {
  63. nRet = ResponseStatus(nDataLen, nCmdPos, nCmdLen,chMsg, byDataFlag);
  64. }
  65. else
  66. {
  67. nRet = -1;
  68. }
  69. #endif
  70. return nRet;
  71. }
  72. int CProtocolModbus::WriteCommand(
  73. int nCommPort, //端口
  74. int nAddr, //地址
  75. int nVer, //版本号
  76. int nCid1, //控制标识码
  77. int nCid2, //命令信息
  78. WORD wLenId, //INFO字节长度
  79. int nCmdType, //命令类型
  80. int nSetValue) //设定值
  81. {
  82. int iResult = 0;
  83. if(!m_pComm)
  84. return ERR_CODE_DAIKIN_COM_FAULT;
  85. iResult = RequestSetParam( nCommPort,
  86. nAddr,
  87. nVer,
  88. nCid1,
  89. nCid2,
  90. wLenId,
  91. nCmdType,
  92. nSetValue);
  93. if (iResult == 0)
  94. {
  95. return ResponseSetParam( nCommPort,
  96. nAddr,
  97. nVer,
  98. nCid1,
  99. nCid2,
  100. wLenId,
  101. nCmdType,
  102. nSetValue);
  103. }
  104. else
  105. {
  106. return iResult;
  107. }
  108. }
  109. int CProtocolModbus::WriteCommand(
  110. int nCommPort, //端口
  111. int nAddr, //地址
  112. int nSetType, //设定类型
  113. int nSetIndex, //设定值索引,只针对特殊变量(例如:空调制冷、制热温度)
  114. int nSetValue) //设定值
  115. {
  116. int iResult = 0;
  117. if(!m_pComm)
  118. return ERR_CODE_DAIKIN_COM_FAULT;
  119. iResult = RequestRemoteCtrl( nCommPort,
  120. nAddr,
  121. nSetType,
  122. nSetIndex,
  123. nSetValue);
  124. if (iResult == 0)
  125. {
  126. return ResponseRemoteCtrl( nCommPort,
  127. nAddr,
  128. nSetType,
  129. nSetIndex,
  130. nSetValue);
  131. }
  132. else
  133. {
  134. return iResult;
  135. }
  136. }
  137. int CProtocolModbus::RequestSetParam(
  138. int nCommPort, //端口
  139. int nAddr, //地址
  140. int nVer, //版本号
  141. int nCid1, //控制标识码
  142. int nCid2, //命令信息
  143. WORD wLenId, //INFO字节长度
  144. int nCmdType, //命令类型
  145. int nSetValue) //设定值
  146. {
  147. int nLen = sizeof(CHILD);
  148. char chLength[4] = {0};
  149. char chChkSum[5] = {0};
  150. CHILD tagRequestChild;
  151. memset( &tagRequestChild, 0, nLen );
  152. //起始位
  153. tagRequestChild.bySoi = 0x7E;
  154. //设备地址描述
  155. tagRequestChild.byAdr[0] = ByteToAscii((nAddr>>4) & 0x0f);
  156. tagRequestChild.byAdr[1] = ByteToAscii(nAddr & 0x0f);
  157. //通讯协议版本
  158. tagRequestChild.byVer[0] = ByteToAscii((nVer>>4) & 0x0f);
  159. tagRequestChild.byVer[1] = ByteToAscii(nVer & 0x0f);
  160. //Cid1
  161. tagRequestChild.byCid1[0] = ByteToAscii((nCid1>>4) & 0x0f);
  162. tagRequestChild.byCid1[1] = ByteToAscii(nCid1 & 0x0f);
  163. //Cid2
  164. tagRequestChild.byCid2[0] = ByteToAscii((nCid2 >> 4) & 0x0f);
  165. tagRequestChild.byCid2[1] = ByteToAscii(nCid2 & 0x0f);
  166. GetDataLength(wLenId, chLength);//取数据长度
  167. tagRequestChild.byLength[0] = ByteToAscii(chLength[0]);
  168. tagRequestChild.byLength[1] = chLength[1];
  169. tagRequestChild.byLength[2] = chLength[2];
  170. tagRequestChild.byLength[3] = chLength[3];
  171. BYTE *pDataBuf = NULL;
  172. int nWriteLen = 0;
  173. REQUESTSETPARAM tagRequestSetParam;
  174. int nSetParamLen = sizeof(REQUESTSETPARAM);
  175. memset( &tagRequestSetParam, 0, nSetParamLen);
  176. memcpy( &tagRequestSetParam.RequestChild, &tagRequestChild, nLen );
  177. //设置命令
  178. tagRequestSetParam.szCmdType[0] = ByteToAscii((nCmdType >> 4) & 0x0f);
  179. tagRequestSetParam.szCmdType[1] = ByteToAscii(nCmdType & 0x0f);
  180. //设置内容
  181. tagRequestSetParam.szCmdInfo[0] = ByteToAscii( (nSetValue >> 12) & 0x000f );
  182. tagRequestSetParam.szCmdInfo[1] = ByteToAscii( (nSetValue >> 8) & 0x000f );
  183. tagRequestSetParam.szCmdInfo[2] = ByteToAscii( (nSetValue >> 4) & 0x000f );
  184. tagRequestSetParam.szCmdInfo[3] = ByteToAscii( nSetValue & 0x000f );
  185. nWriteLen = nSetParamLen - sizeof(tagRequestSetParam.byCheckSum) -
  186. sizeof(tagRequestSetParam.byEoi);
  187. pDataBuf = new BYTE[ nWriteLen ];
  188. memset( pDataBuf, 0, nWriteLen );
  189. memcpy( pDataBuf, &tagRequestSetParam, nWriteLen );
  190. //校验码
  191. GetCheckSum( (char *)pDataBuf + 1, chChkSum, nWriteLen - 1 );
  192. tagRequestSetParam.byCheckSum[0] = chChkSum[0];
  193. tagRequestSetParam.byCheckSum[1] = chChkSum[1];
  194. tagRequestSetParam.byCheckSum[2] = chChkSum[2];
  195. tagRequestSetParam.byCheckSum[3] = chChkSum[3];
  196. tagRequestSetParam.byEoi = 0x0D;
  197. if( WaitForSingleObject( m_hSemComm, 0 ) == WAIT_OBJECT_0 ) // 有信号才写串口
  198. {
  199. ResetEvent( m_hSemComm );
  200. int nResult = WriteMessage( (BYTE *)&tagRequestSetParam, nLen );
  201. if( nResult == nLen )
  202. {
  203. }
  204. else
  205. {
  206. delete []pDataBuf;
  207. SetEvent( m_hSemComm );
  208. return EER_CODE_DAIKIN_COM_WRITE_DATA;
  209. }
  210. }
  211. else
  212. {
  213. delete []pDataBuf;
  214. return ERR_CODE_DAIKIN_COM_BUSY;
  215. }
  216. if( pDataBuf )
  217. {
  218. delete[] pDataBuf;
  219. pDataBuf = NULL;
  220. }
  221. return 0;
  222. }
  223. int CProtocolModbus::ResponseSetParam(
  224. int nCommPort, //端口
  225. int nAddr, //地址
  226. int nVer, //版本号
  227. int nCid1, //控制标识码
  228. int nCid2, //命令信息
  229. WORD wLenId, //INFO字节长度
  230. int nCmdType, //命令类型
  231. int nSetValue) //设定值
  232. {
  233. RESPONSE_STRUCT structResponse;
  234. memset( &structResponse, 0, sizeof(RESPONSE_STRUCT) );
  235. int nLen = sizeof(RESPONSE_STRUCT) - sizeof(structResponse.byRtnMsg);
  236. char *pBuffer = new char[ nLen ];
  237. memset(pBuffer, 0, nLen);
  238. int nProcessLen = 0;
  239. int nReadLen = 0;
  240. nReadLen = ReadMessage((BYTE *)pBuffer, nLen);
  241. if( nReadLen <= 0)
  242. {
  243. // 串口没有读到数据
  244. TRACE("串口没有读到数据!\r\n");
  245. SetEvent( m_hSemComm );
  246. if( pBuffer != NULL)
  247. {
  248. delete[] pBuffer;
  249. pBuffer = NULL;
  250. }
  251. return ERR_CODE_DAIKIN_COM_READ_NO_DATA;
  252. }
  253. else if( nReadLen < nLen )
  254. {
  255. TRACE("长度没有收够,断续接收,止到收完为止!\r\n");
  256. #if DEBUG_PROTOCOL
  257. SetEvent( m_hSemComm );
  258. if( pBuffer )
  259. {
  260. delete[] pBuffer;
  261. pBuffer = NULL;
  262. }
  263. return ERR_CODE_DAIKIN_COM_FAULT;
  264. #else
  265. nProcessLen += nReadLen;
  266. nReadLen = ReadMessage( (BYTE *)(pBuffer + nProcessLen), nLen - nProcessLen );
  267. while( nReadLen != nLen - nProcessLen )
  268. {
  269. if( nReadLen == 0 )
  270. {
  271. SetEvent( m_hSemComm );
  272. if( pBuffer )
  273. {
  274. delete[] pBuffer;
  275. pBuffer = NULL;
  276. }
  277. return ERR_CODE_UPS_PARADIGM_COM_READ_NO_DATA; // 还是没有收到数据,直接返回
  278. }
  279. nProcessLen += nReadLen;
  280. nReadLen = ReadMessage( (BYTE *)(pBuffer + nProcessLen), nLen - nProcessLen);
  281. }
  282. if( nReadLen == nLen )
  283. {
  284. //goto NormalProcess;
  285. if( pBuffer != NULL)
  286. {
  287. delete[] pBuffer;
  288. pBuffer = NULL;
  289. }
  290. return ERR_CODE_UPS_PARADIGM_COM_FAULT;
  291. }
  292. #endif
  293. }
  294. else if( nReadLen > nLen )
  295. {
  296. // 完全代码,不一定能执行到
  297. TRACE("接收的长度超时所需的长度,认为是非法包,扔掉\r\n");
  298. SetEvent( m_hSemComm );
  299. if( pBuffer != NULL)
  300. {
  301. delete[] pBuffer;
  302. pBuffer = NULL;
  303. }
  304. return ERR_CODE_DAIKIN_COM_READ_LEN_OVER;
  305. }
  306. // 判断校验
  307. char chChkSum[5] = {0};
  308. BYTE chTmpChkSum[4] = {0};
  309. GetCheckSum(pBuffer + 1, chChkSum, nLen - sizeof(structResponse.byCheckSum) - 2 );
  310. chTmpChkSum[0] = chChkSum[0];
  311. chTmpChkSum[1] = chChkSum[1];
  312. chTmpChkSum[2] = chChkSum[2];
  313. chTmpChkSum[3] = chChkSum[3];
  314. if (!((chTmpChkSum[0] ==(byte)pBuffer[nLen - 4]) &&
  315. (chTmpChkSum[1] ==(byte)pBuffer[nLen - 3]) &&
  316. (chTmpChkSum[2] ==(byte)pBuffer[nLen - 2]) &&
  317. (chTmpChkSum[3] ==(byte)pBuffer[nLen - 1])))
  318. {
  319. TRACE("校验失败!\r\n");
  320. SetEvent( m_hSemComm );
  321. if( pBuffer != NULL)
  322. {
  323. delete[] pBuffer;
  324. pBuffer = NULL;
  325. }
  326. return ERR_CODE_DAIKIN_COM_LRC_LOST;
  327. }
  328. // 设置串口等待事件为有信号
  329. SetEvent( m_hSemComm );
  330. if( pBuffer != NULL)
  331. {
  332. delete[] pBuffer;
  333. pBuffer = NULL;
  334. }
  335. return 0;
  336. }
  337. int CProtocolModbus::RequestRemoteCtrl(
  338. int nCommPort, //端口
  339. int nAddr, //地址
  340. int nSetType, //设定类型
  341. int nSetIndex, //设定值索引,只针对特殊变量(例如:空调制冷、制热温度)
  342. int nSetValue) //设定值
  343. {
  344. int nLen = sizeof(CHILD);
  345. char chLength[4] = {0};
  346. char chChkSum[5] = {0};
  347. CHILD tagRequestChild;
  348. int nCid1 = 0x60;
  349. int nCid2 = 0x45;
  350. memset( &tagRequestChild, 0, nLen );
  351. //起始位
  352. tagRequestChild.bySoi = 0x7E;
  353. //设备地址描述
  354. tagRequestChild.byAdr[0] = ByteToAscii((nAddr>>4) & 0x0f);
  355. tagRequestChild.byAdr[1] = ByteToAscii(nAddr & 0x0f);
  356. //通讯协议版本
  357. tagRequestChild.byVer[0] = '2';
  358. tagRequestChild.byVer[1] = '0';
  359. //Cid1
  360. tagRequestChild.byCid1[0] = ByteToAscii((nCid1>>4) & 0x0f);
  361. tagRequestChild.byCid1[1] = ByteToAscii(nCid1 & 0x0f);
  362. //Cid2
  363. tagRequestChild.byCid2[0] = ByteToAscii((nCid2 >> 4) & 0x0f);
  364. tagRequestChild.byCid2[1] = ByteToAscii(nCid2 & 0x0f);
  365. //GetDataLength(5, chLength);//取数据长度
  366. tagRequestChild.byLength[0] = 'E';
  367. tagRequestChild.byLength[1] = '0';
  368. tagRequestChild.byLength[2] = '0';
  369. tagRequestChild.byLength[3] = '2';
  370. BYTE *pDataBuf = NULL;
  371. int nWriteLen = 0;
  372. REQUEST_CTRL tagRequestCtrl;
  373. int nRemoteCtrlLen = sizeof(REQUEST_CTRL);
  374. memset( &tagRequestCtrl, 0, nRemoteCtrlLen);
  375. memcpy( &tagRequestCtrl.RequestChild, &tagRequestChild, nLen );
  376. //设置命令
  377. tagRequestCtrl.szCmdType[0] = ByteToAscii((nSetValue >> 4) & 0x0f);
  378. tagRequestCtrl.szCmdType[1] = ByteToAscii(nSetValue & 0x0f);;
  379. nWriteLen = nRemoteCtrlLen - sizeof(tagRequestCtrl.byCheckSum) -
  380. sizeof(tagRequestCtrl.byEoi);
  381. pDataBuf = new BYTE[ nWriteLen ];
  382. memset( pDataBuf, 0, nWriteLen );
  383. memcpy( pDataBuf, &tagRequestCtrl, nWriteLen );
  384. //校验码
  385. GetCheckSum( (char *)pDataBuf + 1, chChkSum, nWriteLen - 1 );
  386. tagRequestCtrl.byCheckSum[0] = chChkSum[0];
  387. tagRequestCtrl.byCheckSum[1] = chChkSum[1];
  388. tagRequestCtrl.byCheckSum[2] = chChkSum[2];
  389. tagRequestCtrl.byCheckSum[3] = chChkSum[3];
  390. tagRequestCtrl.byEoi = 0x0D;
  391. if( WaitForSingleObject( m_hSemComm, 0 ) == WAIT_OBJECT_0 ) // 有信号才写串口
  392. {
  393. ResetEvent( m_hSemComm );
  394. int nResult = WriteMessage( (BYTE *)&tagRequestCtrl, nRemoteCtrlLen );
  395. if( nResult == nRemoteCtrlLen )
  396. {
  397. }
  398. else
  399. {
  400. delete []pDataBuf;
  401. SetEvent( m_hSemComm );
  402. return EER_CODE_DAIKIN_COM_WRITE_DATA;
  403. }
  404. }
  405. else
  406. {
  407. delete []pDataBuf;
  408. return ERR_CODE_DAIKIN_COM_BUSY;
  409. }
  410. if( pDataBuf )
  411. {
  412. delete[] pDataBuf;
  413. pDataBuf = NULL;
  414. }
  415. return 0;
  416. }
  417. int CProtocolModbus::ResponseRemoteCtrl(
  418. int nCommPort, //端口
  419. int nAddr, //地址
  420. int nSetType, //设定类型
  421. int nSetIndex, //设定值索引,只针对特殊变量(例如:空调制冷、制热温度)
  422. int nSetValue) //设定值
  423. {
  424. RESPONSE_STRUCT structResponse;
  425. memset( &structResponse, 0, sizeof(RESPONSE_STRUCT) );
  426. int nLen = sizeof(RESPONSE_STRUCT) - sizeof(structResponse.byRtnMsg);
  427. char *pBuffer = new char[ nLen ];
  428. memset(pBuffer, 0, nLen);
  429. int nProcessLen = 0;
  430. int nReadLen = 0;
  431. nReadLen = ReadMessage((BYTE *)pBuffer, nLen);
  432. if( nReadLen <= 0)
  433. {
  434. // 串口没有读到数据
  435. TRACE("串口没有读到数据!\r\n");
  436. SetEvent( m_hSemComm );
  437. if( pBuffer != NULL)
  438. {
  439. delete[] pBuffer;
  440. pBuffer = NULL;
  441. }
  442. return ERR_CODE_DAIKIN_COM_READ_NO_DATA;
  443. }
  444. else if( nReadLen < nLen )
  445. {
  446. TRACE("长度没有收够,断续接收,止到收完为止!\r\n");
  447. SetEvent( m_hSemComm );
  448. if( pBuffer )
  449. {
  450. delete[] pBuffer;
  451. pBuffer = NULL;
  452. }
  453. return ERR_CODE_DAIKIN_COM_FAULT;
  454. }
  455. else if( nReadLen > nLen )
  456. {
  457. // 完全代码,不一定能执行到
  458. TRACE("接收的长度超时所需的长度,认为是非法包,扔掉\r\n");
  459. SetEvent( m_hSemComm );
  460. if( pBuffer != NULL)
  461. {
  462. delete[] pBuffer;
  463. pBuffer = NULL;
  464. }
  465. return ERR_CODE_DAIKIN_COM_READ_LEN_OVER;
  466. }
  467. // 判断校验
  468. char chChkSum[5] = {0};
  469. BYTE chTmpChkSum[4] = {0};
  470. GetCheckSum(pBuffer + 1, chChkSum, nLen - sizeof(structResponse.byCheckSum) - 2 );
  471. chTmpChkSum[0] = chChkSum[0];
  472. chTmpChkSum[1] = chChkSum[1];
  473. chTmpChkSum[2] = chChkSum[2];
  474. chTmpChkSum[3] = chChkSum[3];
  475. if (!((chTmpChkSum[0] ==(byte)pBuffer[nLen - 5]) &&
  476. (chTmpChkSum[1] ==(byte)pBuffer[nLen - 4]) &&
  477. (chTmpChkSum[2] ==(byte)pBuffer[nLen - 3]) &&
  478. (chTmpChkSum[3] ==(byte)pBuffer[nLen - 2])))
  479. {
  480. TRACE("校验失败!\r\n");
  481. SetEvent( m_hSemComm );
  482. if( pBuffer != NULL)
  483. {
  484. delete[] pBuffer;
  485. pBuffer = NULL;
  486. }
  487. return ERR_CODE_DAIKIN_COM_LRC_LOST;
  488. }
  489. // 设置串口等待事件为有信号
  490. SetEvent( m_hSemComm );
  491. if( pBuffer != NULL)
  492. {
  493. delete[] pBuffer;
  494. pBuffer = NULL;
  495. }
  496. return 0;
  497. }
  498. int CProtocolModbus::ResponseStatus( int nDataLen, int iCmdPos, int iCmdLen, char chMsg[80], char *byDataFlag)
  499. {
  500. #if 1
  501. RESPONSE_STRUCT structResponse;
  502. memset( &structResponse, 0, sizeof(RESPONSE_STRUCT) );
  503. if (nDataLen <= 0)
  504. {
  505. TRACE("变量长度小于等于0,为非法变量");
  506. return ERR_CODE_DAIKIN_COM_VARLEN;
  507. }
  508. int nLen = sizeof(RESPONSE_STRUCT) - sizeof(structResponse.byRtnMsg) + nDataLen;
  509. char *pBuffer = new char[ nLen ];
  510. memset(pBuffer, 0, nLen);
  511. int nProcessLen = 0;
  512. int nReadLen = 0;
  513. nReadLen = ReadMessage((BYTE *)pBuffer, nLen);
  514. if( nReadLen <= 0)
  515. {
  516. // 串口没有读到数据
  517. TRACE("串口没有读到数据!\r\n");
  518. SetEvent( m_hSemComm );
  519. if( pBuffer != NULL)
  520. {
  521. delete[] pBuffer;
  522. pBuffer = NULL;
  523. }
  524. return ERR_CODE_DAIKIN_COM_READ_NO_DATA;
  525. }
  526. else if( nReadLen < nLen )
  527. {
  528. TRACE("长度没有收够,断续接收,止到收完为止!\r\n");
  529. SetEvent( m_hSemComm );
  530. if( pBuffer )
  531. {
  532. delete[] pBuffer;
  533. pBuffer = NULL;
  534. }
  535. return ERR_CODE_DAIKIN_COM_FAULT;
  536. }
  537. else if( nReadLen > nLen )
  538. {
  539. // 完全代码,不一定能执行到
  540. TRACE("接收的长度超时所需的长度,认为是非法包,扔掉\r\n");
  541. SetEvent( m_hSemComm );
  542. if( pBuffer != NULL)
  543. {
  544. delete[] pBuffer;
  545. pBuffer = NULL;
  546. }
  547. return ERR_CODE_DAIKIN_COM_READ_LEN_OVER;
  548. }
  549. #else
  550. //7E 32 30 30 31 36 30 30 30 39 30 33 34 30 30 20 ~20016000903400
  551. //20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
  552. //20 20 20 20 20 20 20 20 20 20 20 30 38 44 31 20 08D1
  553. //20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 30 0
  554. //30 46 36 38 41 0D 0F68A.
  555. RESPONSE_STRUCT structResponse;
  556. memset( &structResponse, 0, sizeof(RESPONSE_STRUCT) );
  557. #if 0
  558. int nLen = 70;
  559. char *pBuffer = new char[ nLen ];
  560. memset(pBuffer, 0, nLen);
  561. pBuffer[0] = 0x7E;
  562. pBuffer[1] = 0x32;
  563. pBuffer[2] = 0x30;
  564. pBuffer[3] = 0x30;
  565. pBuffer[4] = 0x31;
  566. pBuffer[5] = 0x36;
  567. pBuffer[6] = 0x30;
  568. pBuffer[7] = 0x30;
  569. pBuffer[8] = 0x30;
  570. pBuffer[9] = 0x39;
  571. pBuffer[10] = 0x30;
  572. pBuffer[11] = 0x33;
  573. pBuffer[12] = 0x34;
  574. pBuffer[13] = 0x30;
  575. pBuffer[14] = 0x30;
  576. pBuffer[15] = 0x20;
  577. pBuffer[16] = 0x20;
  578. pBuffer[17] = 0x20;
  579. pBuffer[18] = 0x20;
  580. pBuffer[19] = 0x20;
  581. pBuffer[20] = 0x20;
  582. pBuffer[21] = 0x20;
  583. pBuffer[22] = 0x20;
  584. pBuffer[23] = 0x20;
  585. pBuffer[24] = 0x20;
  586. pBuffer[25] = 0x20;
  587. pBuffer[26] = 0x20;
  588. pBuffer[27] = 0x20;
  589. pBuffer[28] = 0x20;
  590. pBuffer[29] = 0x20;
  591. pBuffer[30] = 0x20;
  592. pBuffer[31] = 0x20;
  593. pBuffer[32] = 0x20;
  594. pBuffer[33] = 0x20;
  595. pBuffer[34] = 0x20;
  596. pBuffer[35] = 0x20;
  597. pBuffer[36] = 0x20;
  598. pBuffer[37] = 0x20;
  599. pBuffer[38] = 0x20;
  600. pBuffer[39] = 0x20;
  601. pBuffer[40] = 0x20;
  602. pBuffer[41] = 0x20;
  603. pBuffer[42] = 0x20;
  604. pBuffer[43] = 0x30;
  605. pBuffer[44] = 0x38;
  606. pBuffer[45] = 0x44;
  607. pBuffer[46] = 0x31;
  608. pBuffer[47] = 0x20;
  609. pBuffer[48] = 0x20;
  610. pBuffer[49] = 0x20;
  611. pBuffer[50] = 0x20;
  612. pBuffer[51] = 0x20;
  613. pBuffer[52] = 0x20;
  614. pBuffer[53] = 0x20;
  615. pBuffer[54] = 0x20;
  616. pBuffer[55] = 0x20;
  617. pBuffer[56] = 0x20;
  618. pBuffer[57] = 0x20;
  619. pBuffer[58] = 0x20;
  620. pBuffer[59] = 0x20;
  621. pBuffer[60] = 0x20;
  622. pBuffer[61] = 0x20;
  623. pBuffer[62] = 0x20;
  624. pBuffer[63] = 0x30;
  625. pBuffer[64] = 0x30;
  626. pBuffer[65] = 0x46;
  627. pBuffer[66] = 0x36;
  628. pBuffer[67] = 0x38;
  629. pBuffer[68] = 0x41;
  630. pBuffer[69] = 0x0D;
  631. #endif
  632. //7E 32 30 30 32 36 30 34 33 30 30 30 30 46 44 41
  633. //46 0D
  634. int nLen = 18;
  635. char *pBuffer = new char[ nLen ];
  636. memset(pBuffer, 0, nLen);
  637. pBuffer[0] = 0x7E;
  638. pBuffer[1] = 0x32;
  639. pBuffer[2] = 0x30;
  640. pBuffer[3] = 0x30;
  641. pBuffer[4] = 0x32;
  642. pBuffer[5] = 0x36;
  643. pBuffer[6] = 0x30;
  644. pBuffer[7] = 0x34;
  645. pBuffer[8] = 0x33;
  646. pBuffer[9] = 0x30;
  647. pBuffer[10] = 0x30;
  648. pBuffer[11] = 0x30;
  649. pBuffer[12] = 0x30;
  650. pBuffer[13] = 0x46;
  651. pBuffer[14] = 0x44;
  652. pBuffer[15] = 0x41;
  653. pBuffer[16] = 0x46;
  654. pBuffer[17] = 0x0D;
  655. #endif
  656. // 判断校验
  657. char chChkSum[5] = {0};
  658. BYTE chTmpChkSum[4] = {0};
  659. GetCheckSum(pBuffer + 1, chChkSum, nLen - sizeof(structResponse.byCheckSum) - 2 );
  660. chTmpChkSum[0] = chChkSum[0];
  661. chTmpChkSum[1] = chChkSum[1];
  662. chTmpChkSum[2] = chChkSum[2];
  663. chTmpChkSum[3] = chChkSum[3];
  664. if (!((chTmpChkSum[0] ==(byte)pBuffer[nLen - 5]) &&
  665. (chTmpChkSum[1] ==(byte)pBuffer[nLen - 4]) &&
  666. (chTmpChkSum[2] ==(byte)pBuffer[nLen - 3]) &&
  667. (chTmpChkSum[3] ==(byte)pBuffer[nLen - 2])))
  668. {
  669. TRACE("校验失败!\r\n");
  670. SetEvent( m_hSemComm );
  671. if( pBuffer != NULL)
  672. {
  673. delete[] pBuffer;
  674. pBuffer = NULL;
  675. }
  676. return ERR_CODE_DAIKIN_COM_LRC_LOST;
  677. }
  678. //取变量数据
  679. EnterCriticalSection( &m_csWrFinished );
  680. memcpy( &m_structResponse.RequestChild, pBuffer, sizeof(CHILD) );
  681. byDataFlag[0] = pBuffer[sizeof(CHILD)];
  682. for( int i = 0; i < iCmdLen; i++ )
  683. {
  684. //if( iCmdPos > nLen - sizeof(CHILD) ) break;
  685. chMsg[i] = pBuffer[sizeof(CHILD) + iCmdPos + i];
  686. }
  687. LeaveCriticalSection(&m_csWrFinished);
  688. // 设置串口等待事件为有信号
  689. SetEvent( m_hSemComm );
  690. if( pBuffer != NULL)
  691. {
  692. delete[] pBuffer;
  693. pBuffer = NULL;
  694. }
  695. return 0;
  696. }
  697. int CProtocolModbus::RequestStatus
  698. (
  699. int nAddr, //地址
  700. int nVer, //版本号
  701. int nCid1, //控制标识码
  702. int nCid2, //命令信息
  703. WORD wLenId, //INFO字节长度
  704. int nCmdID, //命令ID
  705. int nDataLen, //请求数据长度
  706. int nCmdPos, //变量索引
  707. int nCmdLen, //变量长度
  708. char chMsg[80], //读到的变量值
  709. char *byDataFlag)
  710. {
  711. int iLen = sizeof(REQUESTPARAM);
  712. char chLength[4] = {0};
  713. char chChkSum[5] = {0};
  714. REQUESTPARAM RequestPara;
  715. memset( &RequestPara, 0, iLen );
  716. //起始位
  717. RequestPara.RequestChild.bySoi = 0x7E;
  718. //通讯协议版本
  719. itoa(nVer, (char *)RequestPara.RequestChild.byVer, 10);
  720. //设备地址描述
  721. itoa(nAddr, (char *)RequestPara.RequestChild.byAdr, 10);
  722. RequestPara.RequestChild.byAdr[0] = ByteToAscii((nAddr>>4) & 0x0f);
  723. RequestPara.RequestChild.byAdr[1] = ByteToAscii(nAddr & 0x0f);
  724. //Cid1
  725. RequestPara.RequestChild.byCid1[0] = ByteToAscii((nCid1>>4) & 0x0f);
  726. RequestPara.RequestChild.byCid1[1] = ByteToAscii(nCid1 & 0x0f);
  727. //Cid2
  728. RequestPara.RequestChild.byCid2[0] = ByteToAscii((nCid2 >> 4) & 0x0f);
  729. RequestPara.RequestChild.byCid2[1] = ByteToAscii(nCid2 & 0x0f);
  730. GetDataLength(wLenId, chLength);//取数据长度
  731. RequestPara.RequestChild.byLength[0] = ByteToAscii(chLength[0]);
  732. RequestPara.RequestChild.byLength[1] = chLength[1];
  733. RequestPara.RequestChild.byLength[2] = chLength[2];
  734. RequestPara.RequestChild.byLength[3] = chLength[3];
  735. //校验码
  736. BYTE *pDataBuf = new BYTE[ iLen - sizeof(RequestPara.byCheckSum) - 1 ];
  737. memset(pDataBuf, 0, iLen - sizeof(RequestPara.byCheckSum) - 1 );
  738. memcpy(pDataBuf, &RequestPara, iLen - sizeof(RequestPara.byCheckSum) - 1 );
  739. GetCheckSum((char *)pDataBuf + 1, chChkSum, iLen - sizeof(RequestPara.byCheckSum) - 2 );
  740. RequestPara.byCheckSum[0] = chChkSum[0];
  741. RequestPara.byCheckSum[1] = chChkSum[1];
  742. RequestPara.byCheckSum[2] = chChkSum[2];
  743. RequestPara.byCheckSum[3] = chChkSum[3];
  744. //结束符
  745. RequestPara.byEoi = 0x0D;
  746. if( WaitForSingleObject( m_hSemComm, 0 ) == WAIT_OBJECT_0 ) // 有信号才写串口
  747. {
  748. ResetEvent( m_hSemComm );
  749. int nResult = WriteMessage( (BYTE *)&RequestPara, iLen );
  750. if( nResult == iLen )
  751. {
  752. }
  753. else
  754. {
  755. delete []pDataBuf;
  756. SetEvent( m_hSemComm );
  757. return EER_CODE_DAIKIN_COM_WRITE_DATA;
  758. }
  759. }
  760. else
  761. {
  762. delete []pDataBuf;
  763. return ERR_CODE_DAIKIN_COM_BUSY;
  764. }
  765. delete[]pDataBuf;
  766. return 0;
  767. }
  768. UINT CProtocolModbus::GetCheckSum(char *pBuf, char chDest[5], int len)
  769. {
  770. WORD iSum = 0;
  771. //unsigned char chCompliment[2] = {0};
  772. for(int i=0; i<len; i++)//求和
  773. {
  774. //TRACE("%x\r\n", pBuf[i]);
  775. iSum += pBuf[i];
  776. }
  777. WORD iCompliment = iSum;
  778. iCompliment = ~iCompliment;//取反
  779. iCompliment++;
  780. //DigitToBinary(iCompliment, chDest, sizeof(chDest));
  781. itoa(iCompliment, chDest, 16);
  782. chDest[0] = lowercase2uppercase(chDest[0]);
  783. chDest[1] = lowercase2uppercase(chDest[1]);
  784. chDest[2] = lowercase2uppercase(chDest[2]);
  785. chDest[3] = lowercase2uppercase(chDest[3]);
  786. return atoi(chDest);
  787. }
  788. WORD CProtocolModbus::GetDataLength(const WORD wLENID, char chLength[4])
  789. {
  790. char szLenID[3] = {0};
  791. //int nLen = 10;
  792. DigitToBinary(wLENID, szLenID, sizeof(szLenID));
  793. char chCheckSum = GetLCheckSum(szLenID, sizeof(szLenID));
  794. chLength[0] = chCheckSum;
  795. chLength[1] = szLenID[0];
  796. chLength[2] = szLenID[1];
  797. chLength[3] = szLenID[2];
  798. return 0;
  799. }
  800. void CProtocolModbus::GetNotvalue(const char *pSrc, char *pDest, int iLen)
  801. {
  802. for(int i=0; i<iLen; i++)
  803. if (pSrc[i] == '1')
  804. pDest[i] = '0';
  805. else
  806. pDest[i] = '1';
  807. }
  808. BOOL CProtocolModbus::InitParam(PPORTPARAM pPortParam, CCommAsyn *pComm)
  809. {
  810. int addr=pPortParam->StartAddr;
  811. m_pComm=pComm;
  812. return TRUE;
  813. }
  814. int DigitToBinary(WORD wdSource, char* pDes, int iBit)
  815. {
  816. char pTmpBuf[16] = {0};
  817. char chBuffer[16] = {0};
  818. //wdSource =htonl(wdSource);
  819. itoa(wdSource, pTmpBuf, 2);
  820. int iLen = (int)strlen(pTmpBuf) - 1;
  821. char chValue[16] = {0};
  822. strcpy(chValue, pTmpBuf);
  823. for (int i =0; i<=iLen; i++)
  824. {
  825. pTmpBuf[i] = chValue[iLen - i];
  826. }
  827. for (int k = 0; k<iBit; k++)
  828. {
  829. if ( 0x00 == pTmpBuf[iBit - k - 1])
  830. chBuffer[k] = 0x30;
  831. else
  832. chBuffer[k] = pTmpBuf[iBit - k - 1];
  833. }
  834. memcpy(pDes, chBuffer, iBit);
  835. return 0;
  836. }
  837. void strReverse( char *str )
  838. {
  839. int l = (int)strlen(str);
  840. for( int i = 0; i < l; i++ )
  841. {
  842. for(int i = 0; i < l; i++)
  843. {
  844. if( str[i] >= 'A' && str[i] <= 'Z' )
  845. {
  846. str[i] += 32;
  847. }
  848. else if(str[i] >= 'a' && str[i] <= 'z')
  849. {
  850. str[i] -= 32;
  851. }
  852. }
  853. }
  854. }
  855. char lowercase2uppercase(BYTE btSrc)
  856. {
  857. if( btSrc >= 'a' && btSrc <= 'z' )
  858. {
  859. return btSrc - 'a' + 'A';
  860. }
  861. return btSrc;
  862. }
  863. char ByteToAscii(BYTE btSrc)
  864. {
  865. char chDest;
  866. if( btSrc < 10 )
  867. {
  868. chDest = (char)(btSrc % 10 + '0');
  869. chDest = lowercase2uppercase(chDest);
  870. return chDest;
  871. }
  872. else
  873. {
  874. chDest = ByteToAscii( btSrc / 10 ) + (char)( btSrc % 10 + '0' );
  875. chDest = lowercase2uppercase(chDest);
  876. return chDest;
  877. }
  878. }
  879. WORD AsciiToBYTE(BYTE btSrc)
  880. {
  881. WORD chDest = (WORD)btSrc;
  882. if ((btSrc >= 'A')&&(btSrc <= 'F'))
  883. {
  884. chDest = chDest - 'A' + 10;
  885. }
  886. else if ((btSrc >= 'a')&&(btSrc <= 'f'))
  887. {
  888. chDest = chDest - 'a' + 10;
  889. }
  890. else if ((btSrc >= '0')&&(btSrc <= '9'))
  891. {
  892. chDest -= '0';
  893. }
  894. return chDest;
  895. }
  896. /*
  897. Convert a binary data buffer to a hex string
  898. str: output (a string like “20ef9a“)
  899. bin: input (a data buffer)
  900. binlen: input (the length of the data buffer)
  901. */
  902. void bin2str(char *str, const unsigned char *bin, int binlen)
  903. {
  904. int i;
  905. for(i=0; i<binlen; i++)
  906. {
  907. str[2*i] = ((bin[i] & 0xF0) >> 4);
  908. str[2*i] = (str[2*i] > 9) ? (str[2*i] + 'A' - 10) : (str[2*i] + '0');
  909. str[2*i+1] = (bin[i] & 0x0F);
  910. str[2*i+1] = (str[2*i+1] > 9) ? (str[2*i+1] + 'A' - 10) : (str[2*i+1] + '0');
  911. }
  912. str[2*i] = '\0';
  913. }
  914. char CProtocolModbus::GetLCheckSum(char *pBuf, int len)
  915. {
  916. //WORD iSum = 0;
  917. char chCompliment = 0;
  918. //unsigned char chCompliment[2] = {0};
  919. for(int i=0; i<len; i++)//求和
  920. {
  921. chCompliment += AsciiToBYTE(pBuf[i]);
  922. //chCompliment += pBuf[i];
  923. }
  924. chCompliment = ~chCompliment;//取反
  925. chCompliment++;
  926. return chCompliment;
  927. }
  928. char CProtocolModbus::GetEvenCheckSum(char *pBuf, int nLen)
  929. {
  930. char szEven;
  931. for( int i = 0; i < nLen; i++ )
  932. {
  933. //szEven = szEven ^ AsciiToBYTE(pBuf[i]);
  934. szEven = szEven ^ pBuf[i];
  935. }
  936. //szEven = ByteToAscii(szEven);
  937. return szEven;
  938. #if 0
  939. unsigned int tmp, *dwp, *dwpend;
  940. unsigned char b;
  941. if(nLen==0) return 0;
  942. dwp=(unsigned int *)pBuf;
  943. dwpend=(unsigned int*)(pBuf+((nLen>>(sizeof(unsigned int)>>1))
  944. <<(sizeof(unsigned int)>>1)));
  945. if(dwp<dwpend)
  946. {
  947. tmp=*dwp;
  948. while(++dwp<dwpend)
  949. {
  950. tmp^=*dwp;
  951. };
  952. b =*((unsigned char*)(&tmp));
  953. b^=*((unsigned char*)(&tmp)+1);
  954. b^=*((unsigned char*)(&tmp)+2);
  955. b^=*((unsigned char*)(&tmp)+3);
  956. }
  957. else
  958. b=0;
  959. pBuf+=nLen-1;
  960. while(pBuf>=(char*)dwpend)
  961. b^=*pBuf--;
  962. return b;
  963. #endif
  964. }