训练营PLSR题目
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 
 
 

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