训练营PLSR题目
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

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