训练营PLSR题目
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 
 

740 Zeilen
20 KiB

  1. #include "modbus.h"
  2. #include "PLSR.h"
  3. uint8_t Coil[1250]; ///<存放线圈的数组
  4. uint8_t Register_H[16384]; ///<寄存器的高字节
  5. uint8_t Register_L[16384]; ///<寄存器的低字节
  6. uint8_t EXRegister_H[10000]; ///<0x10000开始寄存器的高字节
  7. uint8_t EXRegister_L[10000]; ///<0x10000开始寄存器的低字节
  8. uint8_t History[3][512]; /*存放历史的地方*/
  9. uint8_t HistoryLongth[3]; /*历史数据大小的计数*/
  10. uint8_t HistoryLocation; /*当前历史存放到了第几条*/
  11. uint8_t SaveFlag = 0;
  12. uint8_t SentPocket[512];
  13. uint8_t Writr_dat[1024];
  14. /**
  15. * @brief 写单个线圈
  16. * @param[in] addr 写入线圈的地址(第几个线圈)
  17. * @param[in] dat 给线圈写入的值
  18. * @return 无
  19. */
  20. void WriteBit(uint16_t addr,uint8_t dat)
  21. {
  22. uint16_t temp;
  23. temp=addr%8;
  24. if(dat)
  25. {
  26. Coil[addr/8]|= (0x01 << temp);
  27. }
  28. else
  29. {
  30. Coil[addr/8]&=~(0x01 << temp);
  31. }
  32. }
  33. /**
  34. * @brief 读单个线圈
  35. * @param[in] addr 读取线圈的地址(第几个线圈)
  36. * @param[in] *dat 线圈的值放在哪里
  37. * @return 无
  38. */
  39. void ReadBit(uint16_t addr,uint8_t * dat)
  40. {
  41. uint16_t temp;
  42. temp=addr%8;
  43. if((Coil[addr/8])&(0x01 << temp))
  44. {
  45. *dat=0x01;
  46. }
  47. else
  48. {
  49. *dat=0x00;
  50. }
  51. }
  52. /**
  53. * @brief Modbus数据的初始处理
  54. * @param[in] buffer[] 预处理的数据
  55. * @param[in] longth 数据的长度
  56. * @return 无
  57. */
  58. void ProcessModbusFrame(uint8_t buffer[], uint16_t longth)
  59. {
  60. uint8_t crc_8[2], cmdCode;
  61. uint16_t modbusCrc;
  62. modbusCrc = modbus_crc16(buffer, longth - 2);
  63. memcpy(crc_8, &modbusCrc, 2);
  64. cmdCode = buffer[1];
  65. /* 如果通过了CRC校验 */
  66. if (crc_8[0] == buffer[longth - 2] &&
  67. crc_8[1] == buffer[longth - 1])
  68. {
  69. switch (cmdCode)
  70. {
  71. case READ_COIL_CODE: ReadCoilProcess(buffer, longth) /* 读线圈 01 */
  72. ;break;
  73. case WRUTE_MUL_COIL_CODE: WriteMulCoilProcess(buffer, longth) /* 写多线圈 0f */
  74. ;break;
  75. case READ_REGUSTER_CODE: ReadRegisterProcess(buffer, longth) /* 读寄存器 03 */
  76. ;break;
  77. case WRITE_COIL_CODE: WriteCoilProcess(buffer, longth) /* 写线圈 05 */
  78. ;break;
  79. case WRITE_MUL_REGISTER_CODE: WriteMulRegisterProcess(buffer, longth) /* 写多寄存器 10 */
  80. ;break;
  81. case GET_HISTORY_CODE: GetHistory(buffer, longth) /* 获取历史 55 */
  82. ;break;
  83. case READ_ODD_REGUSTER_CODE: ReadOddRegisterProcess(buffer, longth) /* 获取奇数的寄存器 33 */
  84. ;break;
  85. case READ_EXREGUSTER_CODE: ReadEXRegisterProcess(buffer, longth) /* 读0x10000处的寄存器 30*/
  86. ;break;
  87. case WRITE_MUL_EXREGISTER_CODE: WriteEXRegisterProcess(buffer, longth) /* 写0x10000处的寄存器 31*/
  88. ;break;
  89. case WRITE_ONLY_REGISTER: WriteOnlyRegister(buffer, longth)
  90. ;break;
  91. case PLSR_COUNT_CLEAR: PLSRCountClear();
  92. default :ErrorBack(buffer, longth); /* 无效指令码 */
  93. ;break;
  94. }
  95. }
  96. }
  97. /**
  98. * @brief 0x01指令码的执行,读取多线圈
  99. * @param[in] buffer[] 预处理的数据
  100. * @param[in] longth 数据的长度
  101. * @return 无
  102. */
  103. void ReadCoilProcess (uint8_t buffer[], uint16_t longth)
  104. {
  105. uint16_t startPoint, step, modbusCrc; /* 从哪里开始读取,读取了多少线圈 */
  106. uint8_t sentCount, crc_8[2], temp_data, errCode = 0x00, SentData[400]; /* 要发送多少字节的数据。 crc_8是crc的校验值 temp_data用来存放读到的字节 */
  107. startPoint = (buffer[2] << 8 )| buffer[3]; /* 将8位数据组装为16位 */
  108. step = (buffer[4] << 8) | buffer[5]; /* 将8位数据组装为16位 */
  109. sentCount = step / 8; /* 计算要用多少字节发送 */
  110. if (step % 8 != 0 ) sentCount++; /* 补全发送字节 */
  111. memset(SentData, 0, 400);
  112. /* 如果是与本设备通信 */
  113. if (buffer[0] == SLAVES_ADDRES)
  114. {
  115. /* 异常分析 */
  116. if(longth != 8) errCode = 0x04;
  117. if(startPoint > 0x270f || startPoint + step > 0x270f + 1) errCode = 0x02;
  118. if(step == 0 || step > 0x07d0) errCode = 0x03;
  119. if(errCode == 0x00)
  120. {
  121. for (int i = 0; i < step; i++ )/* 循环到获取完整的字节 */
  122. {
  123. ReadBit(startPoint + i, &temp_data);
  124. SentData[i/8] = SentData[i/8] | (temp_data << (i % 8));
  125. }
  126. /* 准备发送应答 */
  127. SentPocket[0] = 0x01;
  128. SentPocket[1] = 0x01;
  129. SentPocket[2] = sentCount;
  130. for (int j = 0; j < sentCount; j++)/* 数据组装 */
  131. {
  132. memcpy( &SentPocket[3 + j], &SentData[j], 1);
  133. }
  134. modbusCrc = modbus_crc16(SentPocket, 3 + sentCount);/* 计算CRC */
  135. memcpy(crc_8, &modbusCrc, 2);
  136. SentPocket[3 + sentCount] = crc_8[0];
  137. SentPocket[4 + sentCount] = crc_8[1];
  138. HAL_UART_Transmit_DMA(&huart1,SentPocket,5 + sentCount);
  139. SaveHistory(buffer, longth);
  140. }
  141. else
  142. {
  143. /* 准备发送应答 */
  144. SentPocket[0] = 0x01;
  145. SentPocket[1] = buffer[1] + 0x80;
  146. SentPocket[2] = errCode;
  147. modbusCrc = modbus_crc16(SentPocket, 3);/* 计算CRC */
  148. memcpy(crc_8, &modbusCrc, 2);
  149. SentPocket[3] = crc_8[0];
  150. SentPocket[4] = crc_8[1];
  151. HAL_UART_Transmit_DMA(&huart1,SentPocket,5);
  152. }
  153. }
  154. }
  155. /**
  156. * @brief 0x0f指令码的执行,写入多线圈
  157. * @param[in] buffer[] 预处理的数据
  158. * @param[in] longth 数据的长度
  159. * @return 无
  160. */
  161. void WriteMulCoilProcess(uint8_t buffer[], uint16_t longth)
  162. {
  163. uint16_t startPoint,step, modbusCrc; /* 从哪里开始写入,写入的终点,写入了多少线圈 */
  164. uint8_t crc_8[2],datCount, errCode = 0x00, sentCount; /* crc_8是crc的校验值,datCount,数据计数,有多少位的数据,Writr_dat存放要写入的数据 */
  165. startPoint = (buffer[2] << 8 )| buffer[3]; /* 将8位数据组装位16位 */
  166. step = (buffer[4] << 8) | buffer[5]; /* 将8位数据组装位16位 */
  167. datCount = buffer[6];
  168. memset(Writr_dat, 0, 1024);
  169. sentCount = step / 8; /* 计算要用多少字节发送 */
  170. if (step % 8 != 0 ) sentCount++; /* 补全发送字节 */
  171. /*数据转移,将buffer内的数据存如写数组。*/
  172. for (int i = 0; i < datCount; i++)
  173. {
  174. Writr_dat[i] = buffer[i + 7];
  175. }
  176. /* 如果是与本设备通信 */
  177. if((buffer[0] == SLAVES_ADDRES || buffer[0] == 0x00))
  178. {
  179. /* 异常分析 */
  180. if(buffer[6] + 9 != longth) errCode = 0x04;
  181. if(startPoint > 0x270f || startPoint + step > 0x270f) errCode = 0x02;
  182. if(step == 0 || step > 0x07b0 || sentCount != datCount) errCode = 0x03;
  183. if(errCode == 0x00)
  184. {
  185. for (int j = 0; j < step; j++)
  186. {
  187. if ((Writr_dat[j / 8]) & (0x01)<<(j % 8))
  188. {
  189. WriteBit(startPoint + j, 0x01);
  190. }
  191. else
  192. {
  193. WriteBit(startPoint + j, 0x00);
  194. }
  195. }
  196. /* 如果不是广播,发送返回消息 */
  197. if(buffer[0] == SLAVES_ADDRES)
  198. {
  199. /* 准备发送应答 */
  200. SentPocket[0] = 0x01;
  201. SentPocket[1] = 0x0f;
  202. SentPocket[2] = buffer[2];
  203. SentPocket[3] = buffer[3];
  204. SentPocket[4] = buffer[4];
  205. SentPocket[5] = buffer[5];
  206. modbusCrc = modbus_crc16(SentPocket, 6);/* 计算CRC */
  207. memcpy(crc_8, &modbusCrc, 2);
  208. SentPocket[6] = crc_8[0];
  209. SentPocket[7] = crc_8[1];
  210. HAL_UART_Transmit_DMA(&huart1,SentPocket,8);
  211. SaveHistory(buffer, longth);
  212. }
  213. }
  214. else if(errCode != 0x00 && buffer[0] == SLAVES_ADDRES)
  215. {
  216. /* 准备发送应答 */
  217. SentPocket[0] = 0x01;
  218. SentPocket[1] = buffer[1] + 0x80;
  219. SentPocket[2] = errCode;
  220. modbusCrc = modbus_crc16(SentPocket, 3);/* 计算CRC */
  221. memcpy(crc_8, &modbusCrc, 2);
  222. SentPocket[3] = crc_8[0];
  223. SentPocket[4] = crc_8[1];
  224. HAL_UART_Transmit_DMA(&huart1,SentPocket,5);
  225. }
  226. }
  227. }
  228. /**
  229. * @brief 0x03指令码的执行,读出输出寄存器
  230. * @param[in] buffer[] 预处理的数据
  231. * @param[in] longth 数据的长度
  232. * @return 无
  233. */
  234. void ReadRegisterProcess(uint8_t buffer[], uint16_t longth)
  235. {
  236. uint16_t startPoint,step, modbusCrc; /* 从哪里开始读取,读取多少寄存器 */
  237. uint8_t crc_8[2], SentData[256], errCode = 0x00;
  238. startPoint = (buffer[2] << 8 )| buffer[3]; /* 将8位数据组装位16位 */
  239. step = (buffer[4] << 8) | buffer[5]; /* 将8位数据组装位16位 */
  240. /* 如果是与本设备通信 */
  241. if (buffer[0] == SLAVES_ADDRES)
  242. {
  243. if(longth != 8) errCode = 0x04;
  244. if(startPoint > 0x270f || startPoint + step > 0x270f + 1) errCode = 0x02;
  245. if(step == 0 || step > 0x007d) errCode = 0x03;
  246. if(errCode == 0x00)
  247. {
  248. for (int i = 0; i < step; i++) /* 将数据存取发出数据缓存 */
  249. {
  250. SentData[i * 2] = Register_H[startPoint + i];
  251. SentData[i * 2 +1 ] = Register_L[startPoint + i];
  252. }
  253. /* 准备发送应答 */
  254. SentPocket[0] = 0x01;
  255. SentPocket[1] = 0x03;
  256. SentPocket[2] = buffer[5] * 2;
  257. for (int j = 0; j < buffer[5] * 2; j++)/* 数据组装 */
  258. {
  259. SentPocket[3+j] = SentData[j];
  260. }
  261. modbusCrc = modbus_crc16(SentPocket, (buffer[5] * 2)+ 3);/* 计算CRC */
  262. memcpy(crc_8, &modbusCrc, 2);
  263. SentPocket[(buffer[5] * 2)+ 3] = crc_8[0];
  264. SentPocket[(buffer[5] * 2)+ 4] = crc_8[1];
  265. HAL_UART_Transmit_DMA(&huart1,SentPocket,(buffer[5] * 2)+ 5 );
  266. SaveHistory(buffer, longth);
  267. }
  268. else
  269. {
  270. /* 准备发送应答 */
  271. SentPocket[0] = 0x01;
  272. SentPocket[1] = buffer[1] + 0x80;
  273. SentPocket[2] = errCode;
  274. modbusCrc = modbus_crc16(SentPocket, 3);/* 计算CRC */
  275. memcpy(crc_8, &modbusCrc, 2);
  276. SentPocket[3] = crc_8[0];
  277. SentPocket[4] = crc_8[1];
  278. HAL_UART_Transmit_DMA(&huart1,SentPocket,5);
  279. }
  280. }
  281. }
  282. /**
  283. * @brief 0x30指令码的执行,读出额外输出寄存器
  284. * @param[in] buffer[] 预处理的数据
  285. * @param[in] longth 数据的长度
  286. * @return 无
  287. */
  288. void ReadEXRegisterProcess(uint8_t buffer[], uint16_t longth)
  289. {
  290. uint16_t startPoint,step, modbusCrc; /* 从哪里开始读取,读取多少寄存器 */
  291. uint8_t crc_8[2], SentData[256], errCode = 0x00;
  292. startPoint = (buffer[2] << 8 )| buffer[3]; /* 将8位数据组装位16位 */
  293. step = (buffer[4] << 8) | buffer[5]; /* 将8位数据组装位16位 */
  294. /* 如果是与本设备通信 */
  295. if (buffer[0] == SLAVES_ADDRES)
  296. {
  297. if(longth != 8) errCode = 0x04;
  298. if(startPoint > 0x270f || startPoint + step > 0x270f + 1) errCode = 0x02;
  299. if(step == 0 || step > 0x007d) errCode = 0x03;
  300. if(errCode == 0x00)
  301. {
  302. for (int i = 0; i < step; i++) /* 将数据存取发出数据缓存 */
  303. {
  304. SentData[i * 2] = EXRegister_H[startPoint + i];
  305. SentData[i * 2 +1 ] = EXRegister_L[startPoint + i];
  306. }
  307. /* 准备发送应答 */
  308. SentPocket[0] = 0x01;
  309. SentPocket[1] = 0x30;
  310. SentPocket[2] = buffer[5] * 2;
  311. for (int j = 0; j < buffer[5] * 2; j++)/* 数据组装 */
  312. {
  313. SentPocket[3+j] = SentData[j];
  314. }
  315. modbusCrc = modbus_crc16(SentPocket, (buffer[5] * 2)+ 3);/* 计算CRC */
  316. memcpy(crc_8, &modbusCrc, 2);
  317. SentPocket[(buffer[5] * 2)+ 3] = crc_8[0];
  318. SentPocket[(buffer[5] * 2)+ 4] = crc_8[1];
  319. HAL_UART_Transmit_DMA(&huart1,SentPocket,(buffer[5] * 2)+ 5 );
  320. SaveHistory(buffer, longth);
  321. }
  322. else
  323. {
  324. /* 准备发送应答 */
  325. SentPocket[0] = 0x01;
  326. SentPocket[1] = buffer[1] + 0x80;
  327. SentPocket[2] = errCode;
  328. modbusCrc = modbus_crc16(SentPocket, 3);/* 计算CRC */
  329. memcpy(crc_8, &modbusCrc, 2);
  330. SentPocket[3] = crc_8[0];
  331. SentPocket[4] = crc_8[1];
  332. HAL_UART_Transmit_DMA(&huart1,SentPocket,5);
  333. }
  334. }
  335. }
  336. /**
  337. * @brief 0x33指令码的执行,读取奇数位寄存器
  338. * @param[in] buffer[] 预处理的数据
  339. * @param[in] longth 数据的长度
  340. * @return 无
  341. */
  342. void ReadOddRegisterProcess(uint8_t buffer[], uint16_t longth)
  343. {
  344. uint16_t startPoint,step, modbusCrc; /* 从哪里开始读取,读取多少寄存器 */
  345. uint8_t crc_8[2], SentData[256], errCode = 0x00;
  346. startPoint = (buffer[2] << 8 )| buffer[3]; /* 将8位数据组装位16位 */
  347. step = (buffer[4] << 8) | buffer[5]; /* 将8位数据组装位16位 */
  348. /* 如果是与本设备通信 */
  349. if (buffer[0] == SLAVES_ADDRES)
  350. {
  351. if(longth != 8) errCode = 0x04;
  352. if(startPoint > 0x270f || startPoint + step > 0x270f + 1 || startPoint % 2 == 0) errCode = 0x02;
  353. if(step == 0 || step > 0x007d) errCode = 0x03;
  354. if(errCode == 0x00)
  355. {
  356. for (int i = 0; i < step * 2; i+= 2) /* 将数据存取发出数据缓存 */
  357. {
  358. SentData[i] = Register_H[startPoint + i];
  359. SentData[i + 1] = Register_L[startPoint + i];
  360. }
  361. /* 准备发送应答 */
  362. SentPocket[0] = 0x01;
  363. SentPocket[1] = 0x33;
  364. SentPocket[2] = step * 2;
  365. for (int j = 0; j < step * 2; j++)/* 数据组装 */
  366. {
  367. SentPocket[3+j] = SentData[j];
  368. }
  369. modbusCrc = modbus_crc16(SentPocket, step * 2 + 3);/* 计算CRC */
  370. memcpy(crc_8, &modbusCrc, 2);
  371. SentPocket[(buffer[5] * 2)+ 3] = crc_8[0];
  372. SentPocket[(buffer[5] * 2)+ 4] = crc_8[1];
  373. HAL_UART_Transmit_DMA(&huart1,SentPocket,(step * 2)+ 5 );
  374. SaveHistory(buffer, longth);
  375. }
  376. else
  377. {
  378. /* 准备发送应答 */
  379. SentPocket[0] = 0x01;
  380. SentPocket[1] = buffer[1] + 0x80;
  381. SentPocket[2] = errCode;
  382. modbusCrc = modbus_crc16(SentPocket, 3);/* 计算CRC */
  383. memcpy(crc_8, &modbusCrc, 2);
  384. SentPocket[3] = crc_8[0];
  385. SentPocket[4] = crc_8[1];
  386. HAL_UART_Transmit_DMA(&huart1,SentPocket,5);
  387. }
  388. }
  389. }
  390. /**
  391. * @brief 0x10指令码的执行,写入多寄存器
  392. * @param[in] buffer[] 预处理的数据
  393. * @param[in] longth 数据的长度
  394. * @return 无
  395. */
  396. void WriteMulRegisterProcess(uint8_t buffer[], uint16_t longth)
  397. {
  398. uint16_t startPoint, step, modbusCrc; /* 从哪里开始写入,写入多少寄存器 */
  399. uint8_t crc_8[2], datCount, errCode = 0x00; /* crc校验;数据计数 */
  400. startPoint = (buffer[2] << 8 )| buffer[3]; /* 将8位数据组装位16位 */
  401. step = (buffer[4] << 8) | buffer[5]; /* 将8位数据组装位16位 */
  402. datCount = buffer[6] / 2;
  403. /* 如果是与本设备通信 */
  404. if ((buffer[0] == SLAVES_ADDRES || buffer[0] == 0x00))
  405. {
  406. if(buffer[6] + 9 != longth) errCode = 0x04;
  407. if(startPoint > 0x270f || startPoint + step > 0x270f + 1) errCode = 0x02;
  408. if(step == 0x00 || step > 0x07b || step * 2 != buffer[6] ) errCode = 0x03;
  409. if(errCode == 0x00)
  410. {
  411. for (int i = 0; i < datCount; i++) /* 数据写入 */
  412. {
  413. Register_H[startPoint + i] = buffer[(i * 2)+ 7];
  414. Register_L[startPoint + i] = buffer[(i * 2)+ 8];
  415. }
  416. /* 如果不是广播,发送返回消息 */
  417. if(buffer[0] == SLAVES_ADDRES)
  418. {
  419. /* 准备发送应答 */
  420. SentPocket[0] = 0x01;
  421. SentPocket[1] = 0x10;
  422. SentPocket[2] = buffer[2];
  423. SentPocket[3] = buffer[3];
  424. SentPocket[4] = buffer[4];
  425. SentPocket[5] = buffer[5];
  426. modbusCrc = modbus_crc16(SentPocket, 6);/* 计算CRC */
  427. memcpy(crc_8, &modbusCrc, 2);
  428. SentPocket[6] = crc_8[0];
  429. SentPocket[7] = crc_8[1];
  430. HAL_UART_Transmit_DMA(&huart1,SentPocket,8);
  431. SaveHistory(buffer, longth);
  432. }
  433. }
  434. else if(errCode != 0x00 && buffer[0] == SLAVES_ADDRES)
  435. {
  436. /* 准备发送应答 */
  437. SentPocket[0] = 0x01;
  438. SentPocket[1] = buffer[1] + 0x80;
  439. SentPocket[2] = errCode;
  440. modbusCrc = modbus_crc16(SentPocket, 3);/* 计算CRC */
  441. memcpy(crc_8, &modbusCrc, 2);
  442. SentPocket[3] = crc_8[0];
  443. SentPocket[4] = crc_8[1];
  444. HAL_UART_Transmit_DMA(&huart1,SentPocket,5);
  445. }
  446. }
  447. }
  448. /**
  449. * @brief 0x31指令码的执行,写入额外多寄存器
  450. * @param[in] buffer[] 预处理的数据
  451. * @param[in] longth 数据的长度
  452. * @return 无
  453. */
  454. void WriteEXRegisterProcess(uint8_t buffer[], uint16_t longth)
  455. {
  456. uint16_t startPoint, step, modbusCrc; /* 从哪里开始写入,写入多少寄存器 */
  457. uint8_t crc_8[2], datCount, errCode = 0x00; /* crc校验;数据计数 */
  458. startPoint = (buffer[2] << 8 )| buffer[3]; /* 将8位数据组装位16位 */
  459. step = (buffer[4] << 8) | buffer[5]; /* 将8位数据组装位16位 */
  460. datCount = buffer[6] / 2;
  461. /* 如果是与本设备通信 */
  462. if ((buffer[0] == SLAVES_ADDRES || buffer[0] == 0x00))
  463. {
  464. if(buffer[6] + 9 != longth) errCode = 0x04;
  465. if(startPoint > 0x270f || startPoint + step > 0x270f + 1) errCode = 0x02;
  466. if(step == 0x00 || step > 0x07b || step * 2 != buffer[6] ) errCode = 0x03;
  467. if(errCode == 0x00)
  468. {
  469. for (int i = 0; i < datCount; i++) /* 数据写入 */
  470. {
  471. EXRegister_H[startPoint + i] = buffer[(i * 2)+ 7];
  472. EXRegister_L[startPoint + i] = buffer[(i * 2)+ 8];
  473. }
  474. /* 如果不是广播,发送返回消息 */
  475. if(buffer[0] == SLAVES_ADDRES)
  476. {
  477. /* 准备发送应答 */
  478. SentPocket[0] = 0x01;
  479. SentPocket[1] = 0x31;
  480. SentPocket[2] = buffer[2];
  481. SentPocket[3] = buffer[3];
  482. SentPocket[4] = buffer[4];
  483. SentPocket[5] = buffer[5];
  484. modbusCrc = modbus_crc16(SentPocket, 6);/* 计算CRC */
  485. memcpy(crc_8, &modbusCrc, 2);
  486. SentPocket[6] = crc_8[0];
  487. SentPocket[7] = crc_8[1];
  488. HAL_UART_Transmit_DMA(&huart1,SentPocket,8);
  489. SaveHistory(buffer, longth);
  490. }
  491. }
  492. else if(errCode != 0x00 && buffer[0] == SLAVES_ADDRES)
  493. {
  494. /* 准备发送应答 */
  495. SentPocket[0] = 0x01;
  496. SentPocket[1] = buffer[1] + 0x80;
  497. SentPocket[2] = errCode;
  498. modbusCrc = modbus_crc16(SentPocket, 3);/* 计算CRC */
  499. memcpy(crc_8, &modbusCrc, 2);
  500. SentPocket[3] = crc_8[0];
  501. SentPocket[4] = crc_8[1];
  502. HAL_UART_Transmit_DMA(&huart1,SentPocket,5);
  503. }
  504. }
  505. }
  506. /**
  507. * @brief 0x05指令码的执行,写入单线圈
  508. * @param[in] buffer[] 预处理的数据
  509. * @param[in] longth 数据的长度
  510. * @return 无
  511. */
  512. void WriteCoilProcess(uint8_t buffer[], uint16_t longth)
  513. {
  514. uint16_t startPoint, State; /* 从哪里开始写入,写入多少寄存器 */
  515. startPoint = (buffer[2] << 8 )| buffer[3]; /* 将8位数据组装位16位 */
  516. State = (buffer[4] << 8) | buffer[5]; /* 将8位数据组装位16位 */
  517. if ((buffer[0] == SLAVES_ADDRES || buffer[0] == 0x00))/* 如果是与本设备通信 */
  518. {
  519. if(State == 0xff00)
  520. {
  521. Coil[startPoint/8]|= (0x01 << (startPoint % 8) );
  522. }
  523. if(State == 0x0000)
  524. {
  525. Coil[startPoint/8]&=~(0x01 << (startPoint % 8) );
  526. }
  527. /* 如果不是广播,发送返回消息 */
  528. if(buffer[0] == SLAVES_ADDRES)
  529. {
  530. memcpy(SentPocket, buffer, longth);
  531. HAL_UART_Transmit_DMA(&huart1, SentPocket, longth);
  532. }
  533. }
  534. }
  535. /**
  536. * @brief 0x06指令码的执行,写入单寄存器
  537. * @param[in] buffer[] 预处理的数据
  538. * @param[in] longth 数据的长度
  539. * @return 无
  540. */
  541. void WriteOnlyRegister(uint8_t buffer[], uint16_t longth)
  542. {
  543. uint16_t startPoint;
  544. startPoint = (buffer[2] << 8 )| buffer[3]; /* 将8位数据组装位16位 */
  545. if ((buffer[0] == SLAVES_ADDRES || buffer[0] == 0x00))/* 如果是与本设备通信 */
  546. {
  547. Register_H[startPoint] = buffer[4];
  548. Register_L[startPoint] = buffer[5];
  549. /* 如果不是广播,发送返回消息 */
  550. if(buffer[0] == SLAVES_ADDRES)
  551. {
  552. memcpy(SentPocket, buffer, longth);
  553. HAL_UART_Transmit_DMA(&huart1, SentPocket, longth);
  554. }
  555. }
  556. }
  557. /**
  558. * @brief 指令码错误的返回报文
  559. * @param[in] buffer[] 预处理的数据
  560. * @param[in] longth 数据的长度
  561. * @return 无
  562. */
  563. void ErrorBack(uint8_t buffer[], uint16_t longth)
  564. {
  565. uint16_t modbusCrc;
  566. uint8_t crc_8[2];
  567. /* 如果是与本设备通信 */
  568. if (buffer[0] == SLAVES_ADDRES)
  569. {
  570. /* 准备发送应答 */
  571. SentPocket[0] = 0x01;
  572. SentPocket[1] = buffer[1] + 0x80;
  573. SentPocket[2] = 0x01;
  574. modbusCrc = modbus_crc16(SentPocket, 3);/* 计算CRC */
  575. memcpy(crc_8, &modbusCrc, 2);
  576. SentPocket[3] = crc_8[0];
  577. SentPocket[4] = crc_8[1];
  578. HAL_UART_Transmit_DMA(&huart1,SentPocket,5);
  579. }
  580. }
  581. /**
  582. * @brief 历史保存
  583. * @param[in] buffer[] 保存的数据
  584. * @param[in] longth 数据的长度
  585. * @return 无
  586. */
  587. void SaveHistory(uint8_t buffer[], uint16_t longth)
  588. {
  589. memcpy(History[HistoryLocation], buffer, longth);
  590. HistoryLongth[HistoryLocation] = longth;
  591. HistoryLocation++;
  592. if(HistoryLocation == 3)
  593. {
  594. HistoryLocation = 0;
  595. }
  596. }
  597. /**
  598. * @brief 历史读取
  599. * @return 无
  600. */
  601. void LoadHistory(void)
  602. {
  603. uint8_t temp;
  604. temp = HistoryLocation;
  605. for(int i = 0; i < 3; i++)
  606. {
  607. if(temp == 3)
  608. {
  609. temp = 0;
  610. }
  611. HAL_UART_Transmit(&huart1, History[temp], HistoryLongth[temp], 0xffff);
  612. temp++;
  613. }
  614. }
  615. /**
  616. * @brief 0x55指令码的执行,输出历史
  617. * @param[in] buffer[] 预处理的数据
  618. * @param[in] longth 数据的长度
  619. * @return 无
  620. */
  621. void GetHistory(uint8_t buffer[], uint16_t longth)
  622. {
  623. /* 如果是与本设备通信 */
  624. if (buffer[0] == SLAVES_ADDRES)
  625. {
  626. LoadHistory();
  627. }
  628. }
  629. /**
  630. * @brief 0x39指令码的执行,输出历史
  631. * @param[in] buffer[] 预处理的数据
  632. * @param[in] longth 数据的长度
  633. * @return 无
  634. */
  635. void PLSRCountClear(void)
  636. {
  637. for(int i = 0; i < 10; i ++)
  638. {
  639. CNT_Only[i] = 0;
  640. }
  641. }
  642. /**
  643. * @brief 读取并还原sram数据。
  644. * @return 无
  645. */
  646. void ModbusLoadSRAM(void)
  647. {
  648. uint32_t temp[256] = {0};
  649. Read_Backup_SRAM(temp,256);
  650. memcpy(SramData, temp, 1024);
  651. for(int i = 0; i < 512; i++)
  652. {
  653. Register_H[i + 4096] = SramData[i * 2];
  654. Register_L[i + 4096] = SramData[i * 2 + 1];
  655. }
  656. }
  657. /**
  658. * @brief 存入sram数据。
  659. * @return 无
  660. */
  661. void ModbusSaveSRAM(void)
  662. {
  663. uint32_t temp[256] = {0};
  664. for (int i = 0; i < 512; i++)
  665. {
  666. SramData[i * 2] = Register_H[i + 4096];
  667. SramData[i * 2 + 1] = Register_L[i + 4096];
  668. }
  669. memcpy(temp, SramData, 1024);
  670. Write_Backup_SRAM(temp, 256);
  671. }