【C++】Modbus通讯

2023-11-12

【C++】Modbus通讯

2016年06月22日 20:37:48 Taily老段 阅读数:10298

版权声明:本文为博主原创文章,未经博主允许不得转载。如遇到疑问,评论会给出答复。学习交流——关注页面微信公众号。【吃良心,拉思想】 https://blog.csdn.net/Taily_Duan/article/details/51736825

 

MODBUS_SERVER.h

MODBUS_SERVER.cpp

MODBUS_SHARE.h

MODBUS_SHARE.cpp

PORT.h

PORT.cpp

 

两个VC++ Modbus通信例子源代码.rar

 

 

modbus 协议编程 C++

MODBUS_SERVER.h

 

 
  1. //Download by http://www.NewXing.com

  2. #if !defined(MSERVERH)

  3. #define MSERVERH

  4.  
  5. #ifdef __cplusplus

  6. extern "C"

  7. {

  8. #endif

  9. /*1.对单个PLC操作*/

  10. /*读一个或多个模拟量 参数:站号,开始地址, 读的数量, 返回数据变量指针 返回:-1表示CRC校验失败,-2表示无应答, 大于零表示接收数据成功*/

  11. char MODBUS_S_ReadMultiRegD(unsigned char rtu, unsigned short int RegAdd, unsigned short int RegCount, short int *list);

  12. /*读一个或多个开关量 参数:站号,开始地址, 读的数量, 返回数据变量指针 返回:-1表示CRC校验失败,-2表示无应答, 大于零表示接收数据成功*/

  13. char MODBUS_S_ReadMultiRegM(unsigned char rtu, unsigned short int RegAdd, unsigned short int RegCount, bool *list);

  14. /*读一个或多个开关量 参数:站号,开始地址, 读的数量, 返回数据变量指针 返回:-1表示CRC校验失败,-2表示无应答, 大于零表示接收数据成功*/

  15. char MODBUS_S_ReadMultiRegM_1x(unsigned char rtu, unsigned short int RegAdd, unsigned short int RegCount, bool *list);

  16. /*写一个模拟量 参数:站号,写地址, 返回数据变量指针 返回:小于零失败,大于零表示成功*/

  17. char MODBUS_S_WriteSingRegD(unsigned char rtu, unsigned short int RegAdd, short int var);

  18. /*写一个模拟量 参数:站号,写地址, 返回数据变量指针 返回:小于零失败,大于零表示成功*/

  19. char MODBUS_S_WriteSingRegM(unsigned char rtu, unsigned short int RegAdd, bool var);

  20.  
  21. /*2.对全部PLC操作*/

  22. char MODBUS_S_A_WriteSingRegD(unsigned short int RegAdd, bool var);

  23. char MODBUS_S_A_WriteSingRegM(unsigned short int RegAdd, short int var);

  24.  
  25. /*3.端口操作*/

  26. char MODBUS_S_Init(unsigned long xPort, unsigned long xBabd, unsigned char xDataSize,

  27. unsigned char xParity, unsigned char xStopBit);

  28. char MODBUS_S_UnInit();

  29.  
  30. #ifdef __cplusplus

  31. }

  32. #endif

  33.  
  34.  
  35. #endif


MODBUS_SERVER.cpp

 

 
  1. #include "stdafx.h"

  2. #include<stdlib.h>

  3. #include<stdio.h>

  4. #include<string.h>

  5. #include "MODBUS_SHARE.h"

  6. #include "MODBUS_SERVER.h"

  7. #include "PORT.h"

  8. //Download by http://www.NewXing.com

  9. unsigned char buff[256];

  10.  
  11. /*1.对单个PLC操作*/

  12. /*读一个或多个模拟量 参数:站号,开始地址, 读的数量, 返回数据变量指针 返回:-1表示CRC校验失败,-2表示无应答, 大于零表示接收数据成功*/

  13. /*40000*/

  14. char MODBUS_S_ReadMultiRegD(unsigned char rtu, unsigned short int RegAdd, unsigned short int RegCount, short int *list)

  15. {

  16. unsigned short int crc16;

  17. unsigned short int crctmp;

  18. short int vartmp;

  19.  
  20. memset(buff, 0x00, 255);

  21. buff[0]= rtu;

  22. buff[1]= 0x03;

  23. buff[2]= (unsigned char)((RegAdd-40001) >> 8);

  24. buff[3]= (unsigned char)(RegAdd-40001);

  25. buff[4]= (unsigned char)(RegCount >> 8);

  26. buff[5]= (unsigned char)RegCount;

  27. crc16= CalcCrcFast(buff, 6);

  28. buff[6]= (unsigned char)(crc16 >> 8);

  29. buff[7]= (unsigned char)crc16;

  30.  
  31. //发送数据

  32. unsigned long strlen;

  33. if(IsOpen())

  34. {

  35. //发送数据

  36. strlen= WriteChar(8, (char *)buff);

  37. if(strlen==8)

  38. {

  39. //读数据

  40. memset(buff, 0x00, 255);

  41. Sleep(50);

  42. strlen= ReadChar(255, (char *)buff, 1000);

  43. if(strlen==0)

  44. {

  45. //无返回

  46. return(-2);

  47. }

  48. else

  49. {

  50. //返回长度有效,解析接收缓冲区

  51. if(strlen== (3+(RegCount *2)+ 2) && buff[0]== rtu && buff[1]== 0x03)

  52. {

  53. crc16= CalcCrcFast(buff, 3+(RegCount*2));

  54. crctmp= buff[strlen-2];

  55. crctmp= crctmp << 8 | buff[strlen-1];

  56. if(crc16== crctmp )

  57. {

  58. for(int i=0; i< RegCount; i++)

  59. {

  60. vartmp= buff[3+(2*i)];

  61. vartmp= vartmp << 8;

  62. vartmp= vartmp | buff[3+((2*i)+1)];

  63.  
  64. list[i]= vartmp;

  65. }

  66. }

  67. else

  68. {

  69. return(-1);

  70. }

  71. }

  72. else

  73. {

  74. return(-1);

  75. }

  76. }

  77. }

  78. else

  79. {

  80. return(-2);

  81. }

  82. }

  83. else

  84. {

  85. return(-2);

  86. }

  87.  
  88. return(1);

  89. }

  90.  
  91. /*读一个或多个开关量 参数:站号,开始地址, 读的数量, 返回数据变量指针 返回:-1表示CRC校验失败,-2表示无应答, 大于零表示接收数据成功*/

  92. /*00000*/

  93. char MODBUS_S_ReadMultiRegM(unsigned char rtu, unsigned short int RegAdd, unsigned short int RegCount, bool *list)

  94. {

  95. unsigned short int crc16;

  96. unsigned short int crctmp;

  97.  
  98. memset(buff, 0x00, 255);

  99. buff[0]= rtu;

  100. buff[1]= 0x01;

  101. buff[2]= (unsigned char)(RegAdd >> 8);

  102. buff[3]= (unsigned char)RegAdd;

  103. buff[4]= (unsigned char)(RegCount >> 8);

  104. buff[5]= (unsigned char)RegCount;

  105. crc16= CalcCrcFast(buff, 6);

  106. buff[6]= (unsigned char)(crc16 >> 8);

  107. buff[7]= (unsigned char)crc16;

  108.  
  109. //发送数据

  110. unsigned long strlen;

  111. if(IsOpen())

  112. {

  113. //发送数据

  114. strlen= WriteChar(8, (char *)buff);

  115. if(strlen==8)

  116. {

  117. //读数据

  118. memset(buff, 0x00, 255);

  119. Sleep(50);

  120. strlen= ReadChar(255, (char *)buff, 1000);

  121. if(strlen==0)

  122. {

  123. //无返回

  124. return(-2);

  125. }

  126. else

  127. {

  128. //返回长度有效,解析接收缓冲区

  129. if(strlen== (3+((RegCount+7)/8)+ 2) && buff[0]== rtu && buff[1]== 0x01)

  130. {

  131. crc16= CalcCrcFast(buff, 3+((RegCount +7)/8));

  132. crctmp= buff[strlen-2];

  133. crctmp= crctmp << 8 | buff[strlen-1];

  134. if(crc16== crctmp )

  135. {

  136. unsigned char row=0, col=0;

  137. for(int i=0; i<RegCount; i++)

  138. {

  139. row= i / 8;

  140. col= i % 8;

  141. list[i]= buff[3 + row] >> col & 0x01;

  142. }

  143. }

  144. else

  145. {

  146. return(-1);

  147. }

  148. }

  149. else

  150. {

  151. return(-1);

  152. }

  153. }

  154. }

  155. else

  156. {

  157. return(-2);

  158. }

  159. }

  160. else

  161. {

  162. return(-2);

  163. }

  164.  
  165. return(1);

  166. }

  167.  
  168. /*读一个或多个开关量 参数:站号,开始地址, 读的数量, 返回数据变量指针 返回:-1表示CRC校验失败,-2表示无应答, 大于零表示接收数据成功*/

  169. /*10000*/

  170. char MODBUS_S_ReadMultiRegM_1x(unsigned char rtu, unsigned short int RegAdd, unsigned short int RegCount, bool *list)

  171. {

  172. unsigned short int crc16;

  173. unsigned short int crctmp;

  174.  
  175. memset(buff, 0x00, 255);

  176. buff[0]= rtu;

  177. buff[1]= 0x02;

  178. buff[2]= (unsigned char)((RegAdd-10001)>> 8);

  179. buff[3]= (unsigned char)(RegAdd-10001);

  180. buff[4]= (unsigned char)(RegCount >> 8);

  181. buff[5]= (unsigned char)RegCount;

  182. crc16= CalcCrcFast(buff, 6);

  183. buff[6]= (unsigned char)(crc16 >> 8);

  184. buff[7]= (unsigned char)crc16;

  185.  
  186. //发送数据

  187. unsigned long strlen;

  188. if(IsOpen())

  189. {

  190. //发送数据

  191. strlen= WriteChar(8, (char *)buff);

  192. if(strlen==8)

  193. {

  194. //读数据

  195. memset(buff, 0x00, 255);

  196. Sleep(50);

  197. strlen= ReadChar(255, (char *)buff, 1000);

  198. if(strlen==0)

  199. {

  200. //无返回

  201. return(-2);

  202. }

  203. else

  204. {

  205. //返回长度有效,解析接收缓冲区

  206. if(strlen== (3+((RegCount+7)/8)+ 2) && buff[0]== rtu && buff[1]== 0x02)

  207. {

  208. crc16= CalcCrcFast(buff, 3+((RegCount +7)/8));

  209. crctmp= buff[strlen-2];

  210. crctmp= crctmp << 8 | buff[strlen-1];

  211. if(crc16== crctmp )

  212. {

  213. unsigned char row=0, col=0;

  214. for(int i=0; i<RegCount; i++)

  215. {

  216. row= i / 8;

  217. col= i % 8;

  218. list[i]= buff[3 + row] >> col & 0x01;

  219. }

  220. }

  221. else

  222. {

  223. return(-1);

  224. }

  225. }

  226. else

  227. {

  228. return(-1);

  229. }

  230. }

  231. }

  232. else

  233. {

  234. return(-2);

  235. }

  236. }

  237. else

  238. {

  239. return(-2);

  240. }

  241.  
  242. return(1);

  243. }

  244.  
  245. /*写一个模拟量 参数:站号,写地址, 返回数据变量指针 返回:小于零失败,大于零表示成功*/

  246. /*40000*/

  247. char MODBUS_S_WriteSingRegD(unsigned char rtu, unsigned short int RegAdd, short int var)

  248. {

  249. unsigned short int crc16;

  250.  
  251. memset(buff, 0x00, 255);

  252. buff[0]= rtu;

  253. buff[1]= 0x06;

  254. buff[2]= (unsigned char)((RegAdd-40001) >> 8);

  255. buff[3]= (unsigned char)(RegAdd-40001);

  256. buff[4]= (unsigned char)(var >> 8);

  257. buff[5]= (unsigned char)var;

  258. crc16= CalcCrcFast(buff, 6);

  259. buff[6]= (unsigned char)(crc16 >> 8);

  260. buff[7]= (unsigned char)crc16;

  261.  
  262. //发送数据

  263. unsigned long strlen;

  264. if(IsOpen())

  265. {

  266. //发送数据

  267. strlen= WriteChar(8, (char *)buff);

  268. if(strlen==8)

  269. {

  270. Sleep(50);

  271. strlen= ReadChar(255, (char *)buff, 1000);

  272. //返回长度有效,解析接收缓冲区

  273. if(!(strlen== 8 && buff[0]== rtu && buff[1]== 0x06))

  274. {

  275. return(-1);

  276. }

  277. }

  278. else

  279. {

  280. return(-1);

  281. }

  282. }

  283. else

  284. {

  285. return(-1);

  286. }

  287.  
  288. return(1);

  289. }

  290.  
  291. /*写一个模拟量 参数:站号,写地址, 返回数据变量指针 返回:小于零失败,大于零表示成功*/

  292. char MODBUS_S_WriteSingRegM(unsigned char rtu, unsigned short int RegAdd, bool var)

  293. {

  294. unsigned short int crc16;

  295.  
  296. memset(buff, 0x00, 255);

  297. buff[0]= rtu;

  298. buff[1]= 0x05;

  299. buff[2]= (unsigned char)(RegAdd >> 8);

  300. buff[3]= (unsigned char)RegAdd;

  301. if(var)

  302. {

  303. buff[4]= 0xff;

  304. buff[5]= 0x00;

  305. }

  306. else

  307. {

  308. buff[4]= 0x00;

  309. buff[5]= 0x00;

  310. }

  311. crc16= CalcCrcFast(buff, 6);

  312. buff[6]= (unsigned char)(crc16 >> 8);

  313. buff[7]= (unsigned char)crc16;

  314.  
  315. //发送数据

  316. unsigned long strlen;

  317. if(IsOpen())

  318. {

  319. //发送数据

  320. Sleep(50);

  321. strlen= WriteChar(8, (char *)buff);

  322. if(strlen==8)

  323. {

  324. Sleep(50);

  325. strlen= ReadChar(255, (char *)buff, 1000);

  326. //返回长度有效,解析接收缓冲区

  327. if(!(strlen== 8 && buff[0]== rtu && buff[1]== 0x05))

  328. {

  329. return(-1);

  330. }

  331. }

  332. else

  333. {

  334. return(-1);

  335. }

  336. }

  337. else

  338. {

  339. return(-1);

  340. }

  341.  
  342. return(1);

  343. }

  344.  
  345. //

  346. /*2.对全部PLC操作*/

  347. char MODBUS_S_A_WriteSingRegD(unsigned short int RegAdd, short int var)

  348. {

  349. unsigned short int crc16;

  350.  
  351. memset(buff, 0x00, 255);

  352. buff[0]= 0xff;

  353. buff[1]= 0x06;

  354. buff[2]= (unsigned char)((RegAdd -40001) >> 8);

  355. buff[3]= (unsigned char)(RegAdd -40001);

  356. buff[4]= (unsigned char)(var >> 8);

  357. buff[5]= (unsigned char)var;

  358. crc16= CalcCrcFast(buff, 6);

  359. buff[6]= (unsigned char)(crc16 >> 8);

  360. buff[7]= (unsigned char)crc16;

  361.  
  362. //发送数据

  363. unsigned long strlen;

  364. if(IsOpen())

  365. {

  366. //发送数据

  367. strlen= WriteChar(8, (char *)buff);

  368. if(strlen!=8)

  369. {

  370. return(-1);

  371. }

  372. }

  373. else

  374. {

  375. return(-1);

  376. }

  377.  
  378. return(1);

  379. }

  380.  
  381. char MODBUS_S_A_WriteSingRegM(unsigned short int RegAdd, bool var)

  382. {

  383. unsigned short int crc16;

  384.  
  385. memset(buff, 0x00, 255);

  386. buff[0]= 0xff;

  387. buff[1]= 0x05;

  388. buff[2]= (unsigned char)(RegAdd >> 8);

  389. buff[3]= (unsigned char)RegAdd;

  390. if(var)

  391. {

  392. buff[4]= 0xff;

  393. buff[5]= 0x00;

  394. }

  395. else

  396. {

  397. buff[4]= 0x00;

  398. buff[5]= 0x00;

  399. }

  400. crc16= CalcCrcFast(buff, 6);

  401. buff[6]= (unsigned char)(crc16 >> 8);

  402. buff[7]= (unsigned char)crc16;

  403.  
  404. //发送数据

  405. unsigned long strlen;

  406. if(IsOpen())

  407. {

  408. //发送数据

  409. strlen= WriteChar(8, (char *)buff);

  410. if(strlen!=8)

  411. {

  412. return(-1);

  413. }

  414. }

  415. else

  416. {

  417. return(-1);

  418. }

  419.  
  420. return(1);

  421. }

  422.  
  423. char MODBUS_S_Init(unsigned long xPort, unsigned long xBabd, unsigned char xDataSize,

  424. unsigned char xParity, unsigned char xStopBit)

  425. {

  426. /*

  427. Parity :

  428. EVENPARITY Even

  429. MARKPARITY Mark

  430. NOPARITY No parity

  431. ODDPARITY Odd

  432. SPACEPARITY Space

  433. */

  434. /*BaudRate:

  435. CBR_110

  436. CBR_19200

  437. CBR_300

  438. CBR_38400

  439. CBR_600

  440. CBR_56000

  441. CBR_1200

  442. CBR_57600

  443. CBR_2400

  444. CBR_115200

  445. CBR_4800

  446. CBR_128000

  447. CBR_9600

  448. CBR_256000

  449. CBR_14400

  450. */

  451. /*

  452. ONESTOPBIT 1 stop bit

  453. ONE5STOPBITS 1.5 stop bits

  454. TWOSTOPBITS

  455. */

  456.  
  457. if(OpenPort(xPort,xBabd,xDataSize,xParity, xStopBit,4096,4096,1000))

  458. {

  459. return(1);

  460. }

  461. else

  462. {

  463. return(0);

  464. }

  465. }

  466.  
  467. char MODBUS_S_UnInit()

  468. {

  469. ClosePort();

  470. return(1);

  471. }


MODBUS_SHARE.h

 

 
  1. //Download by http://www.NewXing.com

  2. #if !defined(MSHAREH)

  3. #define MSHAREH

  4.  
  5. #ifdef __cplusplus

  6. extern "C"

  7. {

  8. #endif

  9.  
  10. unsigned short CalcCrcFast(unsigned char*puchMsg,unsigned short usDataLen);

  11.  
  12. #ifdef __cplusplus

  13. }

  14. #endif

  15.  
  16. #endif


MODBUS_SHARE.cpp

 

 
  1. #include "stdafx.h"

  2. #include "MODBUS_SHARE.h"

  3. //Download by http://www.NewXing.com

  4. const unsigned char m_auchCRCHi[]=

  5. {

  6. 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,

  7. 0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,

  8. 0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,

  9. 0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,

  10. 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,

  11. 0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,

  12. 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,

  13. 0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,

  14. 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,

  15. 0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,

  16. 0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,

  17. 0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,

  18. 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,

  19. 0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,

  20. 0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,

  21. 0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,

  22. 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,

  23. 0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,

  24. 0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,

  25. 0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,

  26. 0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,

  27. 0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,

  28. 0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,

  29. 0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,

  30. 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,

  31. 0x80,0x41,0x00,0xC1,0x81,0x40

  32. }

  33. ;

  34.  
  35. const unsigned char m_auchCRCLo[]=

  36. {

  37. 0x00,0xC0,0xC1,0x01,0xC3,0x03,0x02,0xC2,0xC6,0x06,

  38. 0x07,0xC7,0x05,0xC5,0xC4,0x04,0xCC,0x0C,0x0D,0xCD,

  39. 0x0F,0xCF,0xCE,0x0E,0x0A,0xCA,0xCB,0x0B,0xC9,0x09,

  40. 0x08,0xC8,0xD8,0x18,0x19,0xD9,0x1B,0xDB,0xDA,0x1A,

  41. 0x1E,0xDE,0xDF,0x1F,0xDD,0x1D,0x1C,0xDC,0x14,0xD4,

  42. 0xD5,0x15,0xD7,0x17,0x16,0xD6,0xD2,0x12,0x13,0xD3,

  43. 0x11,0xD1,0xD0,0x10,0xF0,0x30,0x31,0xF1,0x33,0xF3,

  44. 0xF2,0x32,0x36,0xF6,0xF7,0x37,0xF5,0x35,0x34,0xF4,

  45. 0x3C,0xFC,0xFD,0x3D,0xFF,0x3F,0x3E,0xFE,0xFA,0x3A,

  46. 0x3B,0xFB,0x39,0xF9,0xF8,0x38,0x28,0xE8,0xE9,0x29,

  47. 0xEB,0x2B,0x2A,0xEA,0xEE,0x2E,0x2F,0xEF,0x2D,0xED,

  48. 0xEC,0x2C,0xE4,0x24,0x25,0xE5,0x27,0xE7,0xE6,0x26,

  49. 0x22,0xE2,0xE3,0x23,0xE1,0x21,0x20,0xE0,0xA0,0x60,

  50. 0x61,0xA1,0x63,0xA3,0xA2,0x62,0x66,0xA6,0xA7,0x67,

  51. 0xA5,0x65,0x64,0xA4,0x6C,0xAC,0xAD,0x6D,0xAF,0x6F,

  52. 0x6E,0xAE,0xAA,0x6A,0x6B,0xAB,0x69,0xA9,0xA8,0x68,

  53. 0x78,0xB8,0xB9,0x79,0xBB,0x7B,0x7A,0xBA,0xBE,0x7E,

  54. 0x7F,0xBF,0x7D,0xBD,0xBC,0x7C,0xB4,0x74,0x75,0xB5,

  55. 0x77,0xB7,0xB6,0x76,0x72,0xB2,0xB3,0x73,0xB1,0x71,

  56. 0x70,0xB0,0x50,0x90,0x91,0x51,0x93,0x53,0x52,0x92,

  57. 0x96,0x56,0x57,0x97,0x55,0x95,0x94,0x54,0x9C,0x5C,

  58. 0x5D,0x9D,0x5F,0x9F,0x9E,0x5E,0x5A,0x9A,0x9B,0x5B,

  59. 0x99,0x59,0x58,0x98,0x88,0x48,0x49,0x89,0x4B,0x8B,

  60. 0x8A,0x4A,0x4E,0x8E,0x8F,0x4F,0x8D,0x4D,0x4C,0x8C,

  61. 0x44,0x84,0x85,0x45,0x87,0x47,0x46,0x86,0x82,0x42,

  62. 0x43,0x83,0x41,0x81,0x80,0x40

  63. }

  64. ;

  65.  
  66. unsigned short CalcCrcFast(unsigned char*puchMsg,unsigned short usDataLen)

  67. {

  68. unsigned char uchCRCHi=0xFF ;

  69. unsigned char uchCRCLo=0xFF ;

  70. unsigned short uIndex ;

  71.  
  72. while(usDataLen--)

  73. {

  74. uIndex=uchCRCHi^*puchMsg++;

  75. uchCRCHi=uchCRCLo^m_auchCRCHi[uIndex];

  76. uchCRCLo=m_auchCRCLo[uIndex];

  77. }

  78. return(uchCRCHi<<8|uchCRCLo);

  79. }


PORT.h

 

 
  1. //Download by http://www.NewXing.com

  2. #if !defined(MPORT)

  3. #define MPORT

  4.  
  5.  
  6. #ifdef __cplusplus

  7. extern "C"

  8. {

  9. #endif

  10.  
  11. inline bool IsOpen();

  12. bool OpenPort(unsigned long xPort, unsigned long xBabd, unsigned char xDataSize,

  13. unsigned char xParity, unsigned char xStopBit, unsigned long InputBuffSize,

  14. unsigned long OutputBuffSize, unsigned long dwTimerOut);

  15. void ClosePort();

  16. void ClearBuffer();

  17. unsigned long ReadChar(unsigned long dwBufferLength, char *buff, unsigned long dwWaitTime);

  18. unsigned long WriteChar(unsigned long dwBufferLength, char *buff);

  19.  
  20. #ifdef __cplusplus

  21. }

  22. #endif

  23.  
  24. #endif


PORT.cpp

 

 
  1. //Download by http://www.NewXing.com

  2. #include "stdafx.h"

  3. #include <stdio.h>

  4. #include <stdlib.h>

  5. #include <windows.h>

  6. #include "PORT.h"

  7.  
  8. //

  9. DCB dcb;

  10. COMMTIMEOUTS CommTimerOuts;

  11. HANDLE hCom= INVALID_HANDLE_VALUE;

  12.  
  13. OVERLAPPED m_overlappedRead;

  14. OVERLAPPED m_overlappedWrite;

  15.  
  16. //

  17. //通讯端口是否打开

  18. inline bool IsOpen()

  19. {

  20. return hCom != INVALID_HANDLE_VALUE;

  21. }

  22.  
  23. //设置超时

  24. void SetTimerOut(unsigned long dwTimerOut= 5000)

  25. {

  26. if(!IsOpen())

  27. {

  28. return;

  29. }

  30.  
  31. CommTimerOuts.ReadIntervalTimeout= MAXDWORD;

  32. CommTimerOuts.ReadTotalTimeoutConstant= 0;

  33. CommTimerOuts.ReadTotalTimeoutMultiplier= 0;

  34. CommTimerOuts.WriteTotalTimeoutConstant= dwTimerOut;

  35. CommTimerOuts.WriteTotalTimeoutMultiplier= 0;

  36.  
  37. SetCommTimeouts(hCom, &CommTimerOuts);

  38. }

  39.  
  40. //设置DCB参数

  41. bool SetDCBParm(unsigned long xBabd, unsigned char xDataSize,

  42. unsigned char xParity, unsigned char xStopBit)

  43. {

  44. if(!IsOpen())

  45. {

  46. return false;

  47. }

  48.  
  49. if (!GetCommState(hCom, &dcb))

  50. {

  51. #ifdef _DEBUG

  52. printf ("错误: %d << 等到通讯口参数失败.\n", GetLastError());

  53. #endif

  54.  
  55. ClosePort();

  56. return (false);

  57. }

  58. //设置通讯参数

  59. dcb.DCBlength= sizeof(DCB);

  60. dcb.BaudRate = xBabd; // set the baud rate

  61. dcb.ByteSize = xDataSize; // data size, xmit, and rcv

  62. dcb.Parity = xParity; // no parity bit

  63. dcb.StopBits = xStopBit; // one stop bit

  64. if (!SetCommState(hCom, &dcb))

  65. {

  66. #ifdef _DEBUG

  67. printf ("错误: %d << 设置通讯端口参数失败.\n", GetLastError());

  68. #endif

  69. ClosePort();

  70. return (false);

  71. }

  72.  
  73. return true;

  74. }

  75.  
  76. //设置端口缓冲区大小

  77. bool SetPortBuffSize(unsigned long InputBuffSize, unsigned long OutputBuffSize)

  78. {

  79. if(!IsOpen())

  80. {

  81. return false;

  82. }

  83.  
  84. if(!SetupComm(hCom, InputBuffSize, OutputBuffSize))

  85. {

  86. #ifdef _DEBUG

  87. printf ("错误: %d << 设置通讯端口缓冲失败.\n", GetLastError());

  88. #endif

  89. ClosePort();

  90. return (false);

  91. }

  92.  
  93. return true;

  94. }

  95.  
  96. //清理所有缓冲区

  97. void ClearBuffer()

  98. {

  99. if(!IsOpen())

  100. {

  101. return;

  102. }

  103.  
  104. PurgeComm(hCom, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);

  105. }

  106.  
  107. //当前接收缓冲区字节数目;

  108. unsigned long GetInBuffCount()

  109. {

  110. if(!IsOpen())

  111. {

  112. return(0);

  113. }

  114.  
  115. DWORD dwErrorFalgs;

  116. COMSTAT Comstat;

  117.  
  118. ClearCommError(hCom, &dwErrorFalgs, &Comstat);

  119. return Comstat.cbInQue;

  120. }

  121.  
  122. //当前发送缓冲区字节数目;

  123. unsigned long GetOutBuffCount()

  124. {

  125. if(!IsOpen())

  126. {

  127. return false;

  128. }

  129.  
  130. DWORD dwErrorFalgs;

  131. COMSTAT Comstat;

  132.  
  133. ClearCommError(hCom, &dwErrorFalgs, &Comstat);

  134. return Comstat.cbOutQue;

  135. }

  136.  
  137. ///打开串口

  138. bool OpenPort(unsigned long xPort, unsigned long xBabd, unsigned char xDataSize,

  139. unsigned char xParity, unsigned char xStopBit, unsigned long InputBuffSize,

  140. unsigned long OutputBuffSize, unsigned long dwTimerOut)

  141. {

  142. if(IsOpen())

  143. {

  144. ClosePort();

  145. }

  146. //设置事件

  147. memset(&m_overlappedRead,0,sizeof(OVERLAPPED));

  148. m_overlappedRead.hEvent= CreateEvent(NULL,FALSE,TRUE,"portread");

  149. ASSERT(m_overlappedRead.hEvent != INVALID_HANDLE_VALUE);

  150.  
  151. memset(&m_overlappedWrite,0,sizeof(OVERLAPPED));

  152. m_overlappedWrite.hEvent= CreateEvent(NULL,FALSE,TRUE,"portwrite");

  153. ASSERT(m_overlappedWrite.hEvent != INVALID_HANDLE_VALUE);

  154. //取得串口字符

  155. char com_str[255];

  156. strcpy(com_str, "COM");

  157. ltoa(xPort, com_str + 3, 10);

  158. //打开通讯端口

  159. hCom = CreateFile(com_str,

  160. GENERIC_READ | GENERIC_WRITE,

  161. 0,

  162. NULL,

  163. OPEN_EXISTING,

  164. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,

  165. NULL

  166. );

  167. if (hCom == INVALID_HANDLE_VALUE)

  168. {

  169. #ifdef _DEBUG

  170. printf ("错误: %d << 打开通讯口失败,请检查是否已经安装串口设备.\n", GetLastError());

  171. #endif

  172. return (false);

  173. }

  174. SetPortBuffSize(InputBuffSize,OutputBuffSize);

  175. SetDCBParm(xBabd,xDataSize,xParity,xStopBit);

  176. SetTimerOut(dwTimerOut);

  177. //清理缓冲器

  178. PurgeComm(hCom, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);

  179. //启动成功

  180. #ifdef _DEBUG

  181. printf ("成功开启端口 %d.\n", com_str);

  182. #endif

  183. return(true);

  184. }

  185.  
  186. //关闭串口;

  187. void ClosePort()

  188. {

  189. if(IsOpen())

  190. {

  191. CloseHandle(hCom);

  192. hCom= INVALID_HANDLE_VALUE;

  193. }

  194.  
  195. //ResetEvent(m_overlappedRead.hEvent);

  196. //ResetEvent(m_overlappedWrite.hEvent);

  197.  
  198. if(m_overlappedRead.hEvent!=NULL)

  199. {

  200. CloseHandle(m_overlappedRead.hEvent);

  201. }

  202. if(m_overlappedWrite.hEvent!=NULL)

  203. {

  204. CloseHandle(m_overlappedWrite.hEvent);

  205. }

  206. }

  207.  
  208. //异步读数据

  209. unsigned long ReadChar(unsigned long dwBufferLength, char *buff, unsigned long dwWaitTime=20)

  210. {

  211. if(!IsOpen())

  212. {

  213. return(0);

  214. }

  215.  
  216. DWORD dwError;

  217. COMSTAT Stat;

  218. if(::ClearCommError(hCom, &dwError, &Stat) && dwError > 0) //清除错误

  219. {

  220. ::PurgeComm(hCom, PURGE_RXABORT | PURGE_RXCLEAR); /*清除输入缓冲区*/

  221. return 0;

  222. }

  223. if(!Stat.cbInQue)// 缓冲区无数据

  224. {

  225. return 0;

  226. }

  227.  
  228. unsigned long uReadLength = 0;

  229. dwBufferLength = dwBufferLength - 1 > Stat.cbInQue ? Stat.cbInQue : dwBufferLength - 1;

  230. if(!::ReadFile(hCom, buff, dwBufferLength, &uReadLength, &m_overlappedRead)) //2000 下 ReadFile 始终返回 True

  231. {

  232. if(::GetLastError() == ERROR_IO_PENDING) // 结束异步I/O

  233. {

  234. WaitForSingleObject(m_overlappedRead.hEvent, dwWaitTime); //等待20ms

  235. if(!::GetOverlappedResult(hCom, &m_overlappedRead, &uReadLength, false))

  236. {

  237. if(::GetLastError() != ERROR_IO_INCOMPLETE)//其他错误

  238. {

  239. uReadLength = 0;

  240. }

  241. }

  242. }

  243. else

  244. {

  245. uReadLength = 0;

  246. }

  247. }

  248.  
  249. return uReadLength;

  250. }

  251.  
  252. //异步写数据

  253. unsigned long WriteChar(unsigned long dwBufferLength, char *buff)

  254. {

  255. if(!IsOpen())

  256. {

  257. return 0;

  258. }

  259.  
  260. DWORD dwError;

  261. if(ClearCommError(hCom, &dwError, NULL) && dwError > 0) //清除错误

  262. {

  263. PurgeComm(hCom, PURGE_TXABORT | PURGE_TXCLEAR);

  264. }

  265.  
  266. unsigned long uWriteLength = 0;

  267. if(!WriteFile(hCom, buff, dwBufferLength, &uWriteLength, &m_overlappedWrite))

  268. {

  269. if(GetLastError() == ERROR_IO_PENDING)

  270. {

  271. DWORD m_tmp=0;

  272. m_tmp= WaitForSingleObject(m_overlappedWrite.hEvent, 1000);

  273. if(m_tmp== WAIT_TIMEOUT || m_tmp== WAIT_ABANDONED)

  274. {

  275. return(0);

  276. }

  277. else if(m_tmp== WAIT_OBJECT_0)

  278. {

  279. if(!GetOverlappedResult(hCom,&m_overlappedWrite,&uWriteLength,false))

  280. {

  281. return(0);

  282. }

  283. else

  284. {

  285. return uWriteLength;

  286. }

  287. }

  288.  
  289. uWriteLength = 0;

  290. }

  291. }

  292.  
  293. return uWriteLength;

  294. }

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【C++】Modbus通讯 的相关文章

  • 【学习笔记】Python进行数据清洗

    写在前面的话 最近看了一个up主讲基本数据清洗操作 觉得非常好 链接如下 Python 数据清洗 用Python给数据洗澡澡 数据分析 数据清洗 数据预处理 哔哩哔哩 bilibili 评论区也有原数据集和相关代码的链接 不是广告 下面就浅
  • 小程序中scroll-view的下拉刷新和小程序页面的下拉刷新开启方法

    scroll view的下拉刷新 video wxml中
  • ES6---promise详解及用法

    一 什么是Promise Promise是ES6异步编程的一种解决方案 目前最先进的解决方案是async和await的搭配 ES8 但是它们是基于promise的 从语法上讲 Promise是一个对象或者说是构造函数 用来封装异步操作并可以
  • 项目总结之angular4.0中的@viewchild,@Input,@Output

    在项目中遇到了这样一个问题 父页面中需要操作子组件里面的方法 这个时候需要怎么做呢 项目是由ionic3 0和angular4 0构成的 代码如下 child的html页面如下 div class child div class child
  • HDU--3783:ZOJ (水题)

    1 题目源地址 http acm hdu edu cn showproblem php pid 3783 2 源代码 include
  • Java HTTPS客户端如何处理证书

    HTTPS HTTP over Secure Socket Layer 简单讲即HTTP下加入SSL层 HTTPS的安全基础是SSL 参考以前的两篇文章 Java JSSE SSL TLS编程代码实例 单向认证 Java JSSE SSL
  • python-数据分析(12-时间序列)

    Pandas 12 Pandas之时间序列 12 1 时间序列 时间序列前言 时间序列数据在很多领域都是重要的结构化数据形式 比如 金融 神经科学 生态学 物理学 在多个时间点观测的数据形成了时间序列 时间序列可以是固定频率的 也可以是不规
  • 计算机专业论文 方向,计算机专业本科生方向论文题目 计算机专业本科生论文题目怎样取...

    100道 计算机专业本科生方向论文题目供您参考 希望能解决毕业生们的计算机专业本科生论文题目怎样取相关问题 选好题目那就开始写计算机专业本科生论文吧 一 比较好写的计算机专业本科生论文题目 1 对本科生计算机课程教学改革的探讨 2 浅谈对本
  • 《UNIX环境高级编程》笔记 第十三章-守护进程

    1 概念 守护进程 daemon 是生存期长的一种进程 它们常常在系统引导装入时启动 仅在系统关闭时才终止 因为它们没有控制终端 所以说它们是在后台运行的 Linux的大多数服务就是用守护进程实现的 这些守护进程名通常以d结尾 如inetd
  • ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; con

    作业背景 node mysql 附 想必各位点进来都是遇到了这个错误 我们都知道报错提示的是出问题的范围 而在范围内有着许多不确定的因素 抽象些来说就是导致脱发的原因不一定是熬夜 还有可能是压力大 焦虑 疾病等原因 问题描述 ER NOT
  • Centos离线手动安装gcc

    正常联网情况下 在Centos系统中 我们可以使用yum命令很方便的从网络自动下载和安装gcc编译器 但是 由于各种原因 在实际使用中 Centos系统系统不允许介入互联网 所以只能自己手动下载 上传至服务器 再自己安装编译器 网上可以找到
  • 云计算 第3章虚拟化技术(2)

    物理网络与虚拟网络 CPU虚拟化 CPU及指令集 CPU的操作由它所执行的指令确定 这些指令成为机器指令Machine Instruction 目前 X86服务器在企业中的部署与应用越来越广泛 X86是一个Intel通用计算机系列的编号 也
  • Sqoop使用汇总

    命令 查看数据库 sqoop list databases connect jdbc mysql 127 0 0 1 3306 username root password root 查看表 sqoop list tables connec
  • 巨详细,大电流线性电源(LDO)原理,看完你就明白了

    原文来自公众号 工程师看海 上一篇文章介绍了PMOS结构线性电源的基本工作原理 今天结合仿真介绍大电流LDO使用的NMOS 架构基本工作原理 以及其他一些重要的LDO参数 包括PSRR Dropout Voltage等 添加微信 chunh
  • 对于模式的思考

    一是确定那些知识是需要掌握的 第二则是如何掌握 Pattern无疑是需要学习的 但事实是它很容易被遗忘 却很难在实际工作中熟练地运用 方法就是将解决问题的模式与实际中某个重要的应用match起来 1 Structural Pattern D
  • 数据整理——大数据治理的关键技术

    摘要 数据是政府 企业和机构的重要资源 数据治理关注数据资源有效利用的众多方面 如数据资产确权 数据管理 数据开放共享 数据隐私保护等 从数据管理的角度 探讨了数据治理中的一项关键技术 数据整理 介绍了以数据拥有者和直接使用者 行业用户 为
  • 如何引导机器?如何面临人机结合?《​人工智能与人类未来》

    微信公众号 乐生活与爱 公众号曾转载过蔡恒进教授的奇文 意识如何演化 机器何时有自我意识 附着与隧通 心智的工作模式 值得反复也读 我上周听了由北京大学博古睿研究中心 中国人民大学哲学院 中国人民大学哲学与认知科学交叉平台 服务器艺术联合主
  • “孔乙己的长衫”:学历究竟成为敲门砖还是枷锁

    在社会上 学历是一个很重要的指标 学历不高的人 在工作中很难晋升到管理层 学历高的人 则可以获得更多的机会 但事实上 这只是一个表面现象 更多的是学历给人带来的附加值 我虽然知道这世界上有一个孔乙己 但我却并不知道他生活在哪个城市 如果可以
  • css文本超出2行显示...

    可以使用CSS的text overflow和ellipsis属性来实现文本超过2行时显示省略号 设置文本溢出隐藏 使用CSS的overflow属性来将文本溢出部分隐藏 同时使用white space属性来设置文本换行方式为normal或者n

随机推荐

  • 关于struts漏洞

    文章出处 阿里云社区 漏洞扫描 gt 技术运维问题 gt 技术分享 gt Struts2代码执行漏洞 Apache Struts s2 005 远程代码执行漏洞 CVE 2010 1870 受影响版本 Struts 2 0 0 Struts
  • Kconfig:'endmenu' in different file than 'menu'

    问题描述 heat ubuntu AM5728 update u boot 2017 01 g70d59ba v2 0 make ARCH arm menuconfig scripts kconfig mconf Kconfig drive
  • CGAL 点云随机下采样

    目录 一 概述 1 主要函数 二 代码实现 三 结果展示 一 概述 随机删除用户指定的输入点的一部分 1 主要函数 头文件 include
  • 解决PowerShell不显示conda虚拟环境的问题

    目录 1 指令正常执行和结果 2 指令执行异常以及解决办法 问题1 CommandNotFoundError No command conda conda 问题2 conda init powershell执行完毕后 重启PowerShel
  • 工作中经常使用shell脚本

    在工作中我们常用shell脚本处理一些问题 今天在来一些这里整理了一些工作中常用的简单shell脚本 1 更新脚本 bin bash apt get update DEBIAN FRONTEND noninteractive apt get
  • 【C语言】小游戏-扫雷(清屏+递归展开+标记)

    大家好 我是深鱼 目录 一 游戏介绍 二 文件分装 三 代码实现步骤 1 制作简易游戏菜单 2 初始化棋盘 11 11 3 打印棋盘 9 9 4 布置雷 5 计算 x y 周围8个坐标的和 6 排查雷 lt 1 gt 清屏后打印棋盘 lt
  • Python:赋值,浅拷贝(copy)和深拷贝(deepcopy)

    基础知识请查看之前博客 Python 对象 可变对象与不可变对象 赋值 浅拷贝和深拷贝的关键问题 修改一个变量 会不会导致另外拷贝出来的对象的改变 不可变对象 import copy a1 0 a2 a1 a3 copy copy a1 a
  • 使用https://mail.google.com/登录GMail

    原来使用gmail google com登录 登录可以进去 但查看邮件时 总是出现 Oop unable to reach Gmail Please check your internet connection and try again
  • spring-boot后端解决跨域问题

    代码 import cn hutool log Log import cn hutool log LogFactory import com alibaba fastjson JSONObject import org springfram
  • 添加静态路由实现不同网段的路由的通信和不用网段之间设备的通信

    两不同网段的路由器 如何互通 三个案例详解 gzmenghai com
  • 下一代电信城域网设计原则

    下一代电信城域网设计原则 作者 epon 运营商早期建设的IP城域网多采用大L3 小L3的组网模式 核心层旁挂BAS 在运营中遇到很多问题 过大的二层网络 导致网络的安全性 可靠性较差 网络不可管理 传统L3设备 采用低成本ASIC套片 提
  • error:expected '=',',',';','asm'or'_attribute_'

    今天在Linux上调一个存包队列 当用gcc编译时 出现error expected asm or attribute 等错误 这个错误是出现在两个函数上 这两个函数的返回类型是bool 当我把bool类型改为void 再进行编译时 错误就
  • 菜鸟教程《Python 3 教程》笔记(18):File(文件)方法

    菜鸟教程 Python 3 教程 笔记 18 18 File 文件 方法 18 1 open 方法 18 2 file 对象 18 2 1 flush 18 2 2 fileno 18 2 3 isatty 18 2 4 truncate
  • PROFINET趣谈——设备模型

    设备名 MAC地址和IP地址是为了在网络中找到对应设备 而要定位确切的输入 IX1 1 输出 QW2 就需要熟悉设备模型的概念 PROFINET IO的设备类型与PROFIBUS几乎相同 如图所示 设备模型包括若干槽 slot 与子槽 su
  • Java内存泄露监控工具:JVM监控工具介绍

    jstack 如果java程序崩溃生成core文件 jstack工具可以用来获得core文件的java stack和native stack的信息 从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题 另外 jstack工具还可以附
  • BUAA词频统计(树实现)

    问题描述 编写程序统计一个英文文本文件中每个单词的出现次数 词频统计 并将统计结果按单词字典序输出到屏幕上 要求 程序应用二叉排序树 BST 来存储和统计读入的单词 注 在此单词为仅由字母组成的字符序列 包含大写字母的单词应将大写字母转换为
  • Linux 解决vi键盘方向键出现字母的问题

    修改 etc vim vimrc tiny 1 将 set compatible 兼容模式 改成 set nocompatible 非兼容模式 2 添加 set backspace 2 解决退格键无法使用
  • 【完全开源】小安派-Cam-D 摄像头核心板

    文章目录 一 概述 二 系统框图 三 摄像头电路 四 内存卡电路 五 IO引脚说明 六 资料 一 概述 小安派 Cam D AiPi Cam D 是安信可科技为高性能模组Ai M61 32S设计的一款摄像头核心板 引脚完全兼容Ai WB1
  • MFC :CCoolBar 的替代方案 CDockablePane。

    阅读受众需有一定MFC知识储备 技术支持 http www cnblogs com shuhaoc archive 2011 06 26 cdockableform html 在以往很多使用CCoolBar实现窗口停靠功能 但是在VS201
  • 【C++】Modbus通讯

    C Modbus通讯 2016年06月22日 20 37 48 Taily老段 阅读数 10298 版权声明 本文为博主原创文章 未经博主允许不得转载 如遇到疑问 评论会给出答复 学习交流 关注页面微信公众号 吃良心 拉思想 https b