训练营PLSR题目
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 
 
 

695 řádky
19 KiB

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