modbus.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. /**
  2. ************************************************************************************************
  3. * @文件 : fly_modbus.c
  4. * @作者 : 樊春春
  5. * @版本 : V1.0
  6. * @时间 : 2022/05/30 22:46:49
  7. * @邮箱 : [email protected]
  8. * @说明 :
  9. ************************************************************************************************
  10. **/
  11. #include "modbus.h"
  12. INT16U misc_info_buf[BUF_LEN_128] = {0};
  13. INT16U cell_temp_buf[BUF_LEN_512] = {0};
  14. INT16U samkoon_txbuf[BUF_LEN_128] = {0};
  15. /****************************************************
  16. * @函数 : crc_count
  17. * @作者 : 樊春春
  18. * @功能 : 计算CRC数据
  19. * @入参 : addr: 数据指针 num: 数量
  20. * @说明 : 无
  21. *****************************************************/
  22. unsigned short crc_count(const INT8U *addr, int num)
  23. {
  24. unsigned short crc = 0xFFFF;
  25. int i;
  26. while (num--)
  27. {
  28. crc ^= *addr++;
  29. for (i = 0; i < 8; i++)
  30. {
  31. crc = (crc & 0x0001) ? ((crc >> 1) ^ 0xA001) : (crc >> 1);
  32. }
  33. }
  34. return crc;
  35. }
  36. /****************************************************
  37. * @函数 : crc_write
  38. * @作者 : 樊春春
  39. * @功能 : CRC写入
  40. * @入参 : p: 数据指针 data: crc值 count: 写入位置
  41. * @说明 : 无
  42. *****************************************************/
  43. void crc_write(INT8U *p, INT16U data, INT8U count)
  44. {
  45. p = p + (2 * count + 3);
  46. *p++ = (INT8U)data;
  47. *p++ = (INT8U)(data >> 8);
  48. }
  49. /****************************************************
  50. * @函数 : little2big
  51. * @作者 : 樊春春
  52. * @功能 : 小端转大端
  53. * @入参 : buf: 数据指针 count: 个数
  54. * @说明 : 无
  55. *****************************************************/
  56. void little2big(INT16U *buf, INT16U count)
  57. {
  58. INT8U i = 0;
  59. INT8U *p = (INT8U *)buf;
  60. INT8U *p_next = (INT8U *)buf + 1;
  61. char tmp;
  62. for (i = 0; i < 2 * count; i++)
  63. {
  64. tmp = *p;
  65. *p = *p_next;
  66. *p_next = tmp;
  67. p = p + 2;
  68. p_next = p_next + 2;
  69. }
  70. }
  71. /****************************************************
  72. * @函数 : modbus_head
  73. * @作者 : 樊春春
  74. * @功能 : Mosbus头拷贝
  75. * @入参 : des_data: 目标数据指针 src_data: 源数据指针
  76. * @说明 : 无
  77. *****************************************************/
  78. void modbus_head(INT8U *des_data, INT8U *src_data)
  79. {
  80. INT8U i = 0;
  81. for (i = 0; i < 2; i++)
  82. {
  83. *des_data++ = *src_data++;
  84. }
  85. src_data = src_data + 3;
  86. *des_data = (*src_data) * 2;
  87. }
  88. /*--------------------------------------------
  89. ** func :ImportantData_TxGet
  90. ** brief:copy send data;
  91. soc 1th start from 0x4001;
  92. ** para : samkoon_txbuf\misc_info_buf for use
  93. --------------------------------------------*/
  94. void ImportantData_TxGet(INT16U pos, INT16U cnt, INT8U *des_data, INT8U *src_data)
  95. {
  96. INT8U i = 0;
  97. pos = pos - 0x4001; // addr offset 4300 hex
  98. src_data = src_data + pos;
  99. des_data = des_data + 6; // cell txbuf offset:6
  100. for (i = pos; i < cnt; i++)
  101. {
  102. *des_data++ = *src_data++;
  103. }
  104. }
  105. /*---------------------------------------
  106. ** func :Cell_Info_ReadOut
  107. ** brief:copy cell data
  108. 1th start from 0x4301
  109. ** para :none
  110. ---------------------------------------*/
  111. void Cell_Info_ReadOut(INT16U *p)
  112. {
  113. INT8U i, j;
  114. for (i = 0; i < 6; i++)
  115. {
  116. for (j = 0; j < 6; j++)
  117. {
  118. *p++ = 3300;
  119. }
  120. }
  121. // for(i = 0;i < config_get_slave_num(); i++) // without offset
  122. // {
  123. // for(j = 0;j < bmu_get_cell_num(i); j++)
  124. // {
  125. // *p++ = 3300; //bmu_get_cell_vol(i,j);
  126. // }
  127. // }
  128. }
  129. /*---------------------------------------
  130. ** func :Cell_Info_TxGet
  131. ** brief: none
  132. ** para :position \ cnt
  133. ---------------------------------------*/
  134. void Cell_Info_TxGet(INT16U pos, INT16U cnt, INT8U *des_data, INT8U *src_data)
  135. {
  136. INT8U i = 0;
  137. pos = pos - 0x4300; // addr offset 4300 hex
  138. src_data = src_data + pos;
  139. des_data = des_data + 6; // cell txbuf offset:6
  140. for (i = pos; i < cnt; i++)
  141. {
  142. *des_data++ = *src_data++;
  143. }
  144. }
  145. /*---------------------------------------
  146. ** func :Temperature_ReadOut
  147. ** brief:copy temperature data,
  148. 1th start from 0x55C1
  149. offset -40
  150. ** para :none
  151. ---------------------------------------*/
  152. void Temperature_ReadOut(INT16U *p)
  153. {
  154. INT8U i, j;
  155. for (i = 0; i < 6; i++)
  156. {
  157. for (j = 0; j < 6; j++)
  158. {
  159. *p++ = 20;
  160. }
  161. }
  162. // for(i = 0;i < config_get_slave_num(); i++) // without offset //PackNum = (total + (singleNum - 1))/singleNum
  163. // {
  164. // for(j = 0;j < bmu_get_temp_num(i); j++)
  165. // {
  166. // *p++ = bmu_get_cell_temp(i,j);
  167. // }
  168. // }
  169. }
  170. /*---------------------------------------
  171. ** func :Cell_Info_TxGet
  172. ** brief: none
  173. ** para :position \ cnt
  174. ---------------------------------------*/
  175. void Temperature_TxGet(INT16U pos, INT16U cnt, INT8U *des_data, INT8U *src_data)
  176. {
  177. INT8U i = 0;
  178. pos = pos - 0x55c0; // addr offset 55c0 hex
  179. src_data = src_data + pos;
  180. des_data = des_data + 6; // tmp txbuf offset:6
  181. for (i = pos; i < cnt; i++)
  182. {
  183. *des_data++ = *src_data++;
  184. }
  185. }
  186. /*---------------------------------------
  187. ** func :Rtu_TxData_Get()
  188. ** brief: none
  189. ** para :position \ cnt
  190. ---------------------------------------*/
  191. void Rtu_TxData_Get(INT16U pos,
  192. INT16U cnt,
  193. INT16U addr_start,
  194. INT8U fotmat_offset, // fotmat_offset:3
  195. INT8U *des_data,
  196. INT8U *src_data)
  197. {
  198. INT8U i = 0;
  199. if (pos < addr_start)
  200. return;
  201. pos = pos - addr_start; // addr offset 55c0 hex
  202. src_data = src_data + pos * 2;
  203. // des_data = des_data + fotmat_offset;
  204. des_data = (INT8U *)des_data + fotmat_offset;
  205. for (i = 2 * pos; i < 2 * cnt; i++)
  206. {
  207. *des_data++ = *src_data++;
  208. }
  209. }
  210. /*----------------------------------------------
  211. ** @func : samkoon_com_work
  212. ** @brief : BMS with samkoon communication
  213. ** format : xx xx xx xx xx xx xx xx
  214. addr func -reg- -count- -crc-
  215. ans: xx xx xx xx xx....xx xx xx
  216. addr func count- --data-- -crc-
  217. crc:small other:big
  218. -----------------------------------------------*/
  219. void samkoon_com_work(INT8U *rec_data, void (*tx_p)(const INT8U *buf, INT16U len))
  220. {
  221. INT16U register_addr_hmi;
  222. INT16U tmp_crc;
  223. volatile INT16U register_count;
  224. volatile INT8U illegal_flag = 0;
  225. INT8U function_code = 0;
  226. register_addr_hmi = (rec_data[REGISTER_ADDR_H] << 8) + rec_data[REGISTER_ADDR_L];
  227. register_count = (rec_data[COUNT_INDEX_H] << 8) + rec_data[COUNT_INDEX_L];
  228. function_code = rec_data[FUNCTION_CODE_INDEX];
  229. switch (function_code)
  230. {
  231. case FUNC_03:
  232. if ((register_addr_hmi >= MODBUS_ADDR_RACK_REMOTE) && (register_addr_hmi < MODBUS_ADDR_RACK_REMOTE_END))
  233. {
  234. modbus_head((INT8U *)samkoon_txbuf, rec_data);
  235. // Important_Bin_ReadOut(misc_info_buf);
  236. little2big(misc_info_buf, register_count);
  237. Rtu_TxData_Get(register_addr_hmi, register_count, 0xc9, 3, (INT8U *)samkoon_txbuf, (INT8U *)misc_info_buf);
  238. tmp_crc = crc_count((INT8U *)samkoon_txbuf, 2 * register_count + 3);
  239. crc_write((INT8U *)samkoon_txbuf, tmp_crc, register_count);
  240. // samkoon_txbuf[register_count + 2] = tmp_crc;
  241. tx_p((INT8U *)samkoon_txbuf, (2 * register_count + 5));
  242. }
  243. else if ((register_addr_hmi >= MODBUS_ADDR_SOC) && (register_addr_hmi < MODBUS_RACK_END))
  244. {
  245. modbus_head((INT8U *)samkoon_txbuf, rec_data);
  246. // ImportantData_Readout(misc_info_buf);
  247. little2big(misc_info_buf, register_count);
  248. Rtu_TxData_Get(register_addr_hmi, register_count, 0x4101, 3, (INT8U *)samkoon_txbuf, (INT8U *)misc_info_buf);
  249. tmp_crc = crc_count((INT8U *)samkoon_txbuf, 2 * register_count + 3);
  250. crc_write((INT8U *)samkoon_txbuf, tmp_crc, register_count);
  251. // samkoon_txbuf[register_count + 2] = tmp_crc;
  252. tx_p((INT8U *)samkoon_txbuf, (2 * register_count + 5));
  253. }
  254. else if ((register_addr_hmi >= MODBUS_ADDR_CELL) && (register_addr_hmi < MODBUS_CELL_END))
  255. {
  256. modbus_head((INT8U *)samkoon_txbuf, rec_data);
  257. Cell_Info_ReadOut(cell_temp_buf); // read all cell data
  258. little2big(cell_temp_buf, register_count);
  259. Rtu_TxData_Get(register_addr_hmi, register_count, 0x4301, 3, (INT8U *)samkoon_txbuf, (INT8U *)cell_temp_buf);
  260. tmp_crc = crc_count((INT8U *)samkoon_txbuf, 2 * register_count + 3);
  261. crc_write((INT8U *)samkoon_txbuf, tmp_crc, register_count);
  262. // samkoon_txbuf[register_count + 2] = tmp_crc;
  263. tx_p((INT8U *)samkoon_txbuf, (2 * register_count + 5));
  264. }
  265. else if ((register_addr_hmi >= MODBUS_ADDR_TEMP) && (register_addr_hmi < MODBUS_TEMP_END))
  266. {
  267. modbus_head((INT8U *)samkoon_txbuf, rec_data);
  268. Temperature_ReadOut(cell_temp_buf); // read all temp data
  269. little2big(cell_temp_buf, register_count);
  270. Rtu_TxData_Get(register_addr_hmi, register_count, 0x55c1, 3, (INT8U *)samkoon_txbuf, (INT8U *)cell_temp_buf);
  271. tmp_crc = crc_count((INT8U *)samkoon_txbuf, 2 * register_count + 3);
  272. crc_write((INT8U *)samkoon_txbuf, tmp_crc, register_count);
  273. // samkoon_txbuf[register_count + 2] = tmp_crc;
  274. tx_p((INT8U *)samkoon_txbuf, (2 * register_count + 5));
  275. }
  276. else if ((register_addr_hmi >= MODBUS_ADDR_READ_KA) && (register_addr_hmi < MODBUS_KA_END))
  277. {
  278. modbus_head((INT8U *)samkoon_txbuf, rec_data);
  279. // Relay_Bin_Readout(misc_info_buf);
  280. little2big(misc_info_buf, register_count);
  281. Rtu_TxData_Get(register_addr_hmi, register_count, 0x1001, 3, (INT8U *)samkoon_txbuf, (INT8U *)misc_info_buf);
  282. tmp_crc = crc_count((INT8U *)samkoon_txbuf, 2 * register_count + 3);
  283. crc_write((INT8U *)samkoon_txbuf, tmp_crc, register_count);
  284. // samkoon_txbuf[register_count + 2] = tmp_crc;
  285. tx_p((INT8U *)samkoon_txbuf, (2 * register_count + 5));
  286. }
  287. break;
  288. /* do other work... */
  289. case FUNC_05:
  290. break;
  291. default:
  292. illegal_flag = 1;
  293. break;
  294. }
  295. }
  296. void modbus_slave_task(void)
  297. {
  298. INT8U err = 0;
  299. INT8U test_buf[20] = {0};
  300. UartFrame_TypeDef *msg;
  301. while (1)
  302. {
  303. OSTimeDly(200);
  304. iwdg_feed(UART3_DOG);
  305. msg = (UartFrame_TypeDef *)OSMboxPend(uart3_mbox, 50, &err);
  306. if ((err == OS_ERR_NONE) && (msg->len >= 2))
  307. {
  308. if ((msg->buf[0] == 0x00) && (msg->buf[1] == 0xAA) && (msg->buf[2] == 0xBB))
  309. {
  310. test_buf[0] = 0x00;
  311. test_buf[1] = 0xBB;
  312. test_buf[2] = 0xAA;
  313. uart3_dma_send(test_buf, 3);
  314. }
  315. }
  316. }
  317. }