ProtocolModbus.cpp 8.8 KB

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