ProtocolModbus.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. // ProtocolPMC916.cpp: implementation of the CProtocolModbus class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "ProtocolModbus.h"
  6. #include "winsock2.h"
  7. #include "icpdas.h"
  8. #ifdef _DEBUG
  9. #undef THIS_FILE
  10. static char THIS_FILE[]=__FILE__;
  11. #define new DEBUG_NEW
  12. #endif
  13. //////////////////////////////////////////////////////////////////////
  14. // Construction/Destruction
  15. //////////////////////////////////////////////////////////////////////
  16. CProtocolModbus::CProtocolModbus() : CProtocol()
  17. {
  18. MTVERIFY( m_hSemComm = CreateEvent( NULL, TRUE, TRUE, 0 ) );
  19. }
  20. CProtocolModbus::~CProtocolModbus()
  21. {
  22. MTVERIFY( CloseHandle( m_hSemComm ) );
  23. }
  24. int CProtocolModbus::WorkMain(
  25. int nAddr, //设备地址
  26. BYTE Start, //起始位
  27. BYTE StartAddr[2], //起始地址
  28. int nRegNum, //读取的寄存器个数
  29. BYTE FuncCode[2],
  30. int nDataLen,
  31. BYTE byWithAddrFlag,
  32. char chMsg[80])
  33. {
  34. if(!m_pComm)
  35. return ERR_CODE_ICPDAS_COM_FAULT; // 串口通信故障
  36. int nRet;
  37. nRet = RequestStatus( nAddr,
  38. Start,
  39. StartAddr,
  40. nRegNum,
  41. FuncCode );
  42. if( nRet != 0 )
  43. {
  44. return nRet; // 串口忙
  45. }
  46. nRet = ResponseStatus(nDataLen, byWithAddrFlag, chMsg);
  47. return nRet;
  48. }
  49. int CProtocolModbus::ResponseStatus(int nDataLen, BYTE byWithAddrFlag, char chMsg[80])
  50. {
  51. int nLen = 0;
  52. int nProcessLen = 0;
  53. int nReadLen = 0;
  54. RESPONSE_STRUCT structResponse;
  55. memset( &structResponse, 0, sizeof(RESPONSE_STRUCT) );
  56. if (nDataLen <= 0)
  57. {
  58. TRACE("变量长度小于等于0,为非法变量");
  59. SetEvent( m_hSemComm );
  60. return ERR_CODE_ICPDAS_COM_VARLEN;
  61. }
  62. if (byWithAddrFlag == '1')
  63. nLen = sizeof(RESPONSE_STRUCT) - sizeof(structResponse.StrRtnMsg) -
  64. sizeof(structResponse.StatusStruct.RtnByteNum) + nDataLen;
  65. else if (byWithAddrFlag == '0')
  66. nLen = sizeof(RESPONSE_STRUCT) - sizeof(structResponse.StrRtnMsg) -
  67. sizeof(structResponse.StatusStruct.RtnByteNum) -
  68. sizeof(structResponse.StatusStruct.AddrCode) + nDataLen;
  69. char *pBuffer = new char[ nLen ];
  70. memset(pBuffer, 0, nLen);
  71. nReadLen = ReadMessage((BYTE *)pBuffer, nLen);
  72. if( nReadLen <= 0)
  73. {
  74. // 串口没有读到数据
  75. TRACE("串口没有读到数据!\r\n");
  76. SetEvent( m_hSemComm );
  77. if( pBuffer != NULL)
  78. {
  79. delete[] pBuffer;
  80. pBuffer = NULL;
  81. }
  82. return ERR_CODE_ICPDAS_COM_READ_NO_DATA;
  83. }
  84. else if( nReadLen < nLen )
  85. {
  86. if (pBuffer[0] == '?')//无效应答包
  87. {
  88. SetEvent( m_hSemComm );
  89. delete[] pBuffer;
  90. pBuffer = NULL;
  91. return ERR_CODE_ICPDAS_COM_INVALIDRES;
  92. }
  93. TRACE("长度没有收够,断续接收,止到收完为止!\r\n");
  94. #if DEBUG_PROTOCOL
  95. SetEvent( m_hSemComm );
  96. if( pBuffer )
  97. {
  98. delete[] pBuffer;
  99. pBuffer = NULL;
  100. }
  101. return ERR_CODE_ICPDAS_COM_FAULT;
  102. #else
  103. nProcessLen += nReadLen;
  104. nReadLen = ReadMessage( (BYTE *)(pBuffer + nProcessLen), nLen - nProcessLen );
  105. while( nReadLen != nLen - nProcessLen )
  106. {
  107. if( nReadLen == 0 )
  108. {
  109. SetEvent( m_hSemComm );
  110. if( pBuffer )
  111. {
  112. delete[] pBuffer;
  113. pBuffer = NULL;
  114. }
  115. return ERR_CODE_ICPDAS_COM_READ_NO_DATA; // 还是没有收到数据,直接返回
  116. }
  117. nProcessLen += nReadLen;
  118. nReadLen = ReadMessage( (BYTE *)(pBuffer + nProcessLen), nLen - nProcessLen);
  119. }
  120. if( nReadLen == nLen )
  121. {
  122. //goto NormalProcess;
  123. if( pBuffer != NULL)
  124. {
  125. delete[] pBuffer;
  126. pBuffer = NULL;
  127. }
  128. SetEvent( m_hSemComm );
  129. return ERR_CODE_ICPDAS_COM_FAULT;
  130. }
  131. #endif
  132. }
  133. else if( nReadLen > nLen )
  134. {
  135. // 完全代码,不一定能执行到
  136. TRACE("接收的长度超时所需的长度,认为是非法包,扔掉\r\n");
  137. SetEvent( m_hSemComm );
  138. if( pBuffer != NULL)
  139. {
  140. delete[] pBuffer;
  141. pBuffer = NULL;
  142. }
  143. return ERR_CODE_ICPDAS_COM_READ_LEN_OVER;
  144. }
  145. else if(nReadLen == nLen)
  146. {
  147. if (pBuffer[0] == '?') //无效应答包
  148. {
  149. delete[] pBuffer;
  150. pBuffer = NULL;
  151. SetEvent( m_hSemComm );
  152. return ERR_CODE_ICPDAS_COM_INVALIDRES;
  153. }
  154. else if( pBuffer[0] != '>' ) //无效应答包
  155. {
  156. delete[] pBuffer;
  157. pBuffer = NULL;
  158. SetEvent( m_hSemComm );
  159. return ERR_CODE_ICPDAS_COM_INVALIDRES;
  160. }
  161. }
  162. // 判断校验
  163. int nCrease = 0;
  164. memset(&m_structResponse, 0,sizeof(RESPONSE_STRUCT));
  165. nCrease = sizeof(m_structResponse.StatusStruct.Start);
  166. memcpy( &m_structResponse.StatusStruct.Start, pBuffer, nCrease );
  167. if (byWithAddrFlag == '1')
  168. {
  169. memcpy( &m_structResponse.StatusStruct.AddrCode, pBuffer +
  170. nLen,
  171. sizeof(m_structResponse.StatusStruct.AddrCode) );
  172. nCrease += sizeof(m_structResponse.StatusStruct.AddrCode);
  173. }
  174. for( int i = 0; i < nDataLen; i++ )
  175. {
  176. chMsg[i] = pBuffer[nCrease + i];
  177. //m_structResponse.StrRtnMsg[i] = pBuffer[nCrease + i];
  178. }
  179. m_structResponse.StatusStruct.RtnByteNum = nDataLen;
  180. // 设置串口等待事件为有信号
  181. SetEvent( m_hSemComm );
  182. if( pBuffer != NULL)
  183. {
  184. delete[] pBuffer;
  185. pBuffer = NULL;
  186. }
  187. return 0;
  188. }
  189. int CProtocolModbus::RequestStatus(
  190. int nAddr, //设备地址
  191. BYTE Start, //起始位
  192. BYTE StartAddr[2], //起始地址
  193. int nRegNum, //读取的寄存器个数
  194. BYTE FuncCode[2]) //功能码
  195. {
  196. int ivarid = 55;
  197. // CProtocol* protocol;
  198. int iLen = sizeof(REQUESTPARAM);
  199. char *pBuf = new char[iLen];
  200. int iSendLen = 0;
  201. REQUESTPARAM RequestPara;
  202. memset(&RequestPara, 0, iLen);
  203. RequestPara.Start = Start;
  204. memcpy(RequestPara.StartAddr, StartAddr, sizeof(RequestPara.StartAddr));
  205. memcpy(RequestPara.FuncCode, FuncCode, sizeof(RequestPara.FuncCode));
  206. RequestPara.END = 0x0D;
  207. memcpy(pBuf, &RequestPara.Start, sizeof(RequestPara.Start));
  208. iSendLen = iSendLen + sizeof(RequestPara.Start);
  209. BYTE szAddr[2] = {0};
  210. szAddr[0] = ByteToAscii((nAddr >> 4) & 0x0f);
  211. szAddr[1] = ByteToAscii(nAddr & 0x0f);
  212. memcpy(pBuf + iSendLen, szAddr, sizeof(szAddr));
  213. iSendLen = iSendLen + sizeof(szAddr);
  214. if (RequestPara.FuncCode[0] == 'L')
  215. {
  216. memcpy(pBuf + iSendLen, RequestPara.FuncCode, sizeof(RequestPara.FuncCode));
  217. iSendLen = iSendLen + sizeof(RequestPara.FuncCode);
  218. }
  219. else if (RequestPara.FuncCode[0] == '-' && RequestPara.FuncCode[1] == '1')
  220. {
  221. ;
  222. }
  223. else if(RequestPara.FuncCode[1] == 0)
  224. {
  225. memcpy(pBuf + iSendLen, RequestPara.FuncCode, sizeof(RequestPara.FuncCode) - 1);
  226. iSendLen = iSendLen + 1;
  227. }
  228. else
  229. {
  230. memcpy(pBuf + iSendLen, RequestPara.FuncCode + 1, sizeof(RequestPara.FuncCode) - 1);
  231. iSendLen = iSendLen + sizeof(RequestPara.FuncCode) - 1;
  232. }
  233. memcpy(pBuf + iSendLen, &RequestPara.END, sizeof(RequestPara.END));
  234. iSendLen = iSendLen + sizeof(RequestPara.END);
  235. if( WaitForSingleObject( m_hSemComm, 0 ) == WAIT_OBJECT_0 ) // 有信号才写串口
  236. {
  237. ResetEvent( m_hSemComm );
  238. int nResult = WriteMessage((unsigned char *)pBuf, iSendLen);
  239. if( nResult == iSendLen )
  240. {
  241. }
  242. else
  243. {
  244. delete []pBuf;
  245. SetEvent( m_hSemComm );
  246. return EER_CODE_ICPDAS_COM_WRITE_DATA;
  247. }
  248. }
  249. else
  250. {
  251. delete []pBuf;
  252. return ERR_CODE_ICPDAS_COM_BUSY;
  253. }
  254. delete []pBuf;
  255. return 0;
  256. }
  257. BOOL CProtocolModbus::InitParam(PPORTPARAM pPortParam, CCommAsyn *pComm)
  258. {
  259. int addr=pPortParam->StartAddr;
  260. m_pComm=pComm;
  261. return TRUE;
  262. }
  263. int CProtocolModbus:: WriteCommand(char DataBuffer[80], int nDataLen)
  264. {
  265. int iResult = 0;
  266. if(!m_pComm)
  267. return ERR_CODE_ICPDAS_COM_FAULT;
  268. iResult = RequestWrStatus(DataBuffer, nDataLen);
  269. if (iResult == 0)
  270. return ResponseWrStatus(DataBuffer, nDataLen);
  271. else
  272. return iResult;
  273. }
  274. int CProtocolModbus::RequestWrStatus( char DataBuffer[80], int nDataLen)//请求写数据
  275. {
  276. //ClearBuffer();
  277. char chBuf[10] = {0};
  278. memset(chBuf, 0, sizeof(chBuf));
  279. ReadMessage((BYTE *)chBuf, sizeof(chBuf));
  280. ResetEvent( m_hSemComm );
  281. int iResult = WriteMessage((unsigned char *)DataBuffer, nDataLen);
  282. if (iResult == nDataLen)
  283. {
  284. return 0;
  285. }
  286. else
  287. {
  288. SetEvent( m_hSemComm );
  289. return EER_CODE_ICPDAS_COM_WRITE_DATA;
  290. }
  291. }
  292. int CProtocolModbus::ResponseWrStatus( char DataBuffer[80], int nDataLen)
  293. {
  294. char chBuf[10] = {0};
  295. memset(chBuf, 0, sizeof(chBuf));
  296. int iReadLen = ReadMessage((BYTE *)chBuf, sizeof(chBuf));
  297. if( iReadLen <= 0) // 串口没有读到数据
  298. {
  299. SetEvent( m_hSemComm );
  300. return ERR_CODE_ICPDAS_COM_READ_NO_DATA;
  301. }
  302. SetEvent( m_hSemComm );
  303. if (chBuf[0] == '>')
  304. {
  305. return 0;
  306. }
  307. else
  308. {
  309. return ERR_CODE_ICPDAS_COM_INVALIDRES;
  310. }
  311. }
  312. void strReverse( char *str )
  313. {
  314. int l = strlen(str);
  315. for( int i = 0; i < l; i++ )
  316. {
  317. for(int i = 0; i < l; i++)
  318. {
  319. if( str[i] >= 'A' && str[i] <= 'Z' )
  320. {
  321. str[i] += 32;
  322. }
  323. else if(str[i] >= 'a' && str[i] <= 'z')
  324. {
  325. str[i] -= 32;
  326. }
  327. }
  328. }
  329. }
  330. char lowercase2uppercase(BYTE btSrc)
  331. {
  332. if( btSrc >= 'a' && btSrc <= 'z' )
  333. {
  334. return btSrc - 'a' + 'A';
  335. }
  336. return btSrc;
  337. }
  338. char ByteToAscii(BYTE btSrc)
  339. {
  340. char chDest;
  341. if( btSrc < 10 )
  342. {
  343. chDest = (char)(btSrc % 10 + '0');
  344. chDest = lowercase2uppercase(chDest);
  345. return chDest;
  346. }
  347. else
  348. {
  349. chDest = ByteToAscii( btSrc / 10 ) + (char)( btSrc % 10 + '0' );
  350. chDest = lowercase2uppercase(chDest);
  351. return chDest;
  352. }
  353. }
  354. WORD AsciiToBYTE(BYTE btSrc)
  355. {
  356. WORD chDest = (WORD)btSrc;
  357. if ((btSrc >= 'A')&&(btSrc <= 'F'))
  358. {
  359. chDest = chDest - 'A' + 10;
  360. }
  361. else if ((btSrc >= 'a')&&(btSrc <= 'f'))
  362. {
  363. chDest = chDest - 'a' + 10;
  364. }
  365. else if ((btSrc >= '0')&&(btSrc <= '9'))
  366. {
  367. chDest -= '0';
  368. }
  369. return chDest;
  370. }