CommPowerModule.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. #include "head.h"
  2. #ifdef BATTERY_WITH_COMM
  3. static const BYTE c_frameStartByte_1 = 0xEB; // 帧起始字符1
  4. static const BYTE c_frameStartByte_2 = 0x90; // 帧起始字符2
  5. static const BYTE c_frameBasisBytes = 0x04; // 帧基础长度 2(帧头) + 1(表示长度) + 1(校验和)
  6. static SIGNAL_FLG g_signalFlag;
  7. static BYTE calcByteSum(BYTE *pbuf, int total)
  8. {
  9. int i;
  10. BYTE sum = 0;
  11. for(i=0; i<total; i++)
  12. sum += pbuf[i];
  13. return sum;
  14. }
  15. static void parseRecvFrame(COMM_POW_MOD *p_instance, BYTE *pbuf)
  16. {
  17. bool ctrl_ret;
  18. BYTE func = pbuf[4];
  19. BYTE son_type = pbuf[5];
  20. BYTE *p_data = &pbuf[6];
  21. switch(func)
  22. {
  23. case RX_READ_FUNC:
  24. if(son_type == 0x01){
  25. p_instance->tYc.batVolt = (WORD)(p_data[0]*256 + p_data[1]);
  26. p_instance->tYc.capacityVolt = (WORD)(p_data[2]*256 + p_data[3]);
  27. g_sw_pub.ac_in[PUB_AC_IN_UZ2] = (qs16)((float)p_instance->tYc.batVolt/100*Q16_BASE);
  28. }else if(son_type == 0x02){
  29. #ifdef BATTERY_BP_L500
  30. p_instance->tYx.yxStatus = (WORD)((p_data[0]>>8) + p_data[1]);
  31. #else
  32. p_instance->tYx.yxStatus = p_data[0];
  33. #endif
  34. p_instance->tYx.BIT.lostVolt = p_instance->tYx.yxStatus&0x0001;
  35. p_instance->tYx.BIT.lowVolt = (p_instance->tYx.yxStatus>>2)&0x0001;
  36. p_instance->tYx.BIT.actStatus = (p_instance->tYx.yxStatus>>1)&0x0001;
  37. p_instance->tYx.BIT.offline = (p_instance->tYx.yxStatus>>4)&0x0001;
  38. #ifdef BATTERY_BP_L500
  39. p_instance->tYx.BIT.R_Alarm = (p_instance->tYx.yxStatus>>8)&0x0001;
  40. p_instance->tYx.BIT.OverHeat = (p_instance->tYx.yxStatus>>9)&0x0001;
  41. #endif
  42. #ifdef FUNC_SEL_BAT_MODULE
  43. p_instance->tYx.BIT.rConnect = (p_instance->tYx.yxStatus>>5)&0x0001;
  44. p_instance->tYx.BIT.backup = (p_instance->tYx.yxStatus>>6)&0x0001;
  45. p_instance->tYx.BIT.capAlarm = (p_instance->tYx.yxStatus>>7)&0x0001;
  46. p_instance->tYx.BIT.overVolt = (p_instance->tYx.yxStatus>>3)&0x0001;
  47. g_run_stu.dcgygj =p_instance->tYx.BIT.overVolt;
  48. g_run_stu.dcfzgj= p_instance->tYx.BIT.rConnect;
  49. g_run_stu.dcbyjlsd= p_instance->tYx.BIT.backup;
  50. g_run_stu.dcrlgz =p_instance->tYx.BIT.capAlarm;
  51. if(soe_check(EV_BAT_OVER_GJ) != g_run_stu.dcgygj){
  52. soe_record_ev(EV_BAT_OVER_GJ, g_run_stu.dcgygj, 0, 0, 0);
  53. }
  54. if(soe_check(EV_BAT_OFFLINE) != g_run_stu.dclxgj){
  55. soe_record_ev(EV_BAT_OFFLINE, g_run_stu.dclxgj, 0, 0, 0);
  56. }
  57. if(soe_check(EV_BAT_REVERSE) != g_run_stu.dcfzgj){
  58. soe_record_ev(EV_BAT_REVERSE, g_run_stu.dcfzgj, 0, 0, 0);
  59. }
  60. if(soe_check(EV_AC_BACKLOST) != g_run_stu.dcbyjlsd){
  61. soe_record_ev(EV_AC_BACKLOST, g_run_stu.dcbyjlsd, 0, 0, 0);
  62. }
  63. if(soe_check(EV_RL_ERR) != g_run_stu.dcrlgz){
  64. soe_record_ev(EV_RL_ERR, g_run_stu.dcrlgz, 0, 0, 0);
  65. }
  66. #endif
  67. g_run_stu.dcjlsd = p_instance->tYx.BIT.lostVolt;
  68. g_run_stu.dcqy = p_instance->tYx.BIT.lowVolt;
  69. g_run_stu.dchh = p_instance->tYx.BIT.actStatus;
  70. g_run_stu.dcdygz = p_instance->tYx.BIT.offline;
  71. if(soe_check(EV_BATERR) != g_run_stu.dcqy){
  72. soe_record_ev(EV_BATERR, g_run_stu.dcqy, 0, 0, 0);
  73. }
  74. if(soe_check(EV_BAT_ACT) != g_run_stu.dchh){
  75. soe_record_ev(EV_BAT_ACT, g_run_stu.dchh, 0, 0, 0);
  76. }
  77. if(soe_check(EV_AC_LOST) != g_run_stu.dcjlsd){
  78. soe_record_ev(EV_AC_LOST, g_run_stu.dcjlsd, 0, 0, 0);
  79. }
  80. }else if(son_type == 0x03){
  81. p_instance->tRunParam.dischargeTimeMax = (WORD)(p_data[0]*256 + p_data[1]);
  82. p_instance->tRunParam.dischargeTimeNow = (WORD)(p_data[2]*256 + p_data[3]);
  83. g_sw_pub.ac_in[PUB_AC_BATT_ACT_T_MAX] = (qs16)((float)p_instance->tRunParam.dischargeTimeMax/60*Q16_BASE);
  84. g_sw_pub.ac_in[PUB_AC_BATT_ACT_T_NOW] = (qs16)((float)p_instance->tRunParam.dischargeTimeNow/60*Q16_BASE);
  85. // rt_printf("电池最大放电时间=%d 电池放电时长=%d \r\n",p_instance->tRunParam.dischargeTimeMax,p_instance->tRunParam.dischargeTimeNow);
  86. }
  87. #ifdef BATTERY_BP_L500
  88. else if(son_type == 0x10)
  89. {
  90. p_instance->tRunParam.BatteryInResist = (WORD)((p_data[0]>>8) + p_data[1]);
  91. g_sw_pub.ac_in[PUB_AC_BATT_R] = (qs16)((float)p_instance->tRunParam.BatteryInResist*Q16_BASE);
  92. }
  93. else if(son_type == 0x11)
  94. {
  95. p_instance->tRunParam.BatteryTemp = (WORD)((p_data[0]>>8) + p_data[1]);
  96. g_sw_pub.ac_in[PUB_AC_BATT_TEMP] = (qs16)((float)p_instance->tRunParam.BatteryTemp*Q16_BASE);
  97. }
  98. else if(son_type == 0x12)
  99. {
  100. p_instance->tRunParam.BatteryRtPower = (WORD)((p_data[0]>>8) + p_data[1]);
  101. g_sw_pub.ac_in[PUB_AC_BATT_RT_POWER] = (qs16)((float)p_instance->tRunParam.BatteryRtPower*Q16_BASE);
  102. }
  103. else if(son_type == 0x0D)
  104. {
  105. p_instance->tRunParam.BatDischageCurrent = (WORD)((p_data[2]>>8) + p_data[3]);
  106. p_instance->tRunParam.BatRechageCurrent = (WORD)((p_data[4]>>8) + p_data[5]);
  107. g_sw_pub.ac_in[PUB_AC_BATT_DISCHARGE_CURRENT] = (qs16)((float)p_instance->tRunParam.BatDischageCurrent*Q16_BASE);
  108. g_sw_pub.ac_in[PUB_AC_BATT_RECHARGE_CURRENT] = (qs16)((float)p_instance->tRunParam.BatRechageCurrent*Q16_BASE);
  109. }
  110. #endif
  111. break;
  112. case RX_WRITE_FUNC:
  113. if(p_data[0] == 0x01)
  114. ctrl_ret = true;
  115. else
  116. ctrl_ret = false;
  117. if(son_type == 0x01){
  118. g_signalFlag.BIT.wActStartRet = ctrl_ret;
  119. }else if(son_type == 0x02){
  120. g_signalFlag.BIT.wActStopRet = ctrl_ret;
  121. }else if(son_type == 0x03){
  122. g_signalFlag.BIT.wDischargeStopRet = ctrl_ret;
  123. }
  124. #ifdef BATTERY_BP_L500
  125. else if(son_type == 0x0A)
  126. {
  127. g_signalFlag.BIT.wBattRRet = ctrl_ret;
  128. if(g_signalFlag.BIT.wBattRRet)
  129. {
  130. rt_printf_time("电池内阻检测成功\r\n");
  131. }
  132. else
  133. {
  134. rt_printf_time("电池内阻检测失败!!\r\n");
  135. }
  136. }
  137. #endif
  138. break;
  139. case CFG_PARAM_FUNC:
  140. break;
  141. case READ_CFG_PARAM_FUNC:
  142. break;
  143. default:
  144. // rt_printf("接收帧功能码错误!\r\n");
  145. break;
  146. }
  147. }
  148. static void processRecv(COMM_POW_MOD *p_instance)
  149. {
  150. int i;
  151. BYTE equ_addr;
  152. BYTE calc_sum;
  153. int frame_len;
  154. int unparse_len;
  155. BYTE tmp_buf[TX_BUF_SIZE_MAX];
  156. if(!p_instance->bData)
  157. return;
  158. p_instance->bData = false;
  159. p_instance->commFault = false;
  160. p_instance->sendMesgCount = 0;
  161. if(soe_check(EV_DYSTATUS)){
  162. soe_record_ev(EV_DYSTATUS, 0, 0, 0, 0);
  163. }
  164. while(p_instance->recvPos != p_instance->parsePos){
  165. if(p_instance->recvBuf[p_instance->parsePos] != c_frameStartByte_1 || p_instance->recvBuf[(p_instance->parsePos+1)%RX_BUF_SIZE_MAX] != c_frameStartByte_2){
  166. p_instance->parsePos = (p_instance->parsePos + 1) % RX_BUF_SIZE_MAX;
  167. // rt_printf("接收帧报文帧头错误!\r\n");
  168. continue;
  169. }
  170. unparse_len = (RX_BUF_SIZE_MAX + p_instance->recvPos - p_instance->parsePos) % RX_BUF_SIZE_MAX;
  171. frame_len = c_frameBasisBytes + p_instance->recvBuf[(p_instance->parsePos+2)%RX_BUF_SIZE_MAX];
  172. if(unparse_len < frame_len){
  173. // rt_printf("未接收到完整的一帧报文!\r\n");
  174. break;
  175. }
  176. if(frame_len > TX_BUF_SIZE_MAX){
  177. // rt_printf("接收帧长越限!\r\n");
  178. break;
  179. }
  180. for(i=0; i<frame_len; i++){
  181. tmp_buf[i] = p_instance->recvBuf[(p_instance->parsePos + i) % RX_BUF_SIZE_MAX];
  182. }
  183. equ_addr = tmp_buf[3];
  184. calc_sum = calcByteSum(tmp_buf,frame_len-1);
  185. p_instance->parsePos = (p_instance->parsePos + frame_len) % RX_BUF_SIZE_MAX;
  186. /*if(calc_sum != tmp_buf[frame_len-1] || equ_addr != p_instance->equAddr){
  187. // rt_printf("接收帧校验和或者装置地址错误!\r\n");
  188. continue;
  189. }*/
  190. if(equ_addr != p_instance->equAddr){
  191. //rt_printf("装置地址错误!\r\n");
  192. continue;
  193. }
  194. parseRecvFrame(p_instance,tmp_buf);
  195. }
  196. }
  197. static void addFrameToSendBuff(COMM_POW_MOD *p_instance, BYTE *pbuf, int len)
  198. {
  199. SERIAL_COMM *port = &g_tRsComm[p_instance->portChannel];
  200. port->sendbuf[0] = len; // 第一个字节为长度
  201. memcpy(&port->sendbuf[1], pbuf, len);
  202. port->bSend = TRUE;
  203. port->nSendCnt = 1;
  204. }
  205. static void sendFixedFrame(COMM_POW_MOD *p_instance,BYTE func,BYTE son_type)
  206. {
  207. int pos=0;
  208. BYTE calc_sum;
  209. BYTE tx_buf[TX_BUF_SIZE_MAX];
  210. tx_buf[pos++] = c_frameStartByte_1;
  211. tx_buf[pos++] = c_frameStartByte_2;
  212. tx_buf[pos++] = 0x03;
  213. tx_buf[pos++] = p_instance->equAddr;
  214. tx_buf[pos++] = func;
  215. tx_buf[pos++] = son_type;
  216. calc_sum = calcByteSum(tx_buf,pos);
  217. tx_buf[pos++] = calc_sum;
  218. addFrameToSendBuff(p_instance,tx_buf,pos);
  219. }
  220. static void sendActInfoClearFrame(COMM_POW_MOD *p_instance)
  221. {
  222. int pos=0;
  223. BYTE calc_sum;
  224. BYTE tx_buf[TX_BUF_SIZE_MAX];
  225. const WORD c_battCap = 0x07; // 电池容量
  226. const WORD c_ActDischargeEndVolt = 1800; // 活化放电截止电压18V
  227. const WORD c_BattLowCapAlarm = 50; // 电池剩余容量告警值 50%
  228. tx_buf[pos++] = c_frameStartByte_1;
  229. tx_buf[pos++] = c_frameStartByte_2;
  230. tx_buf[pos++] = 0x09;
  231. tx_buf[pos++] = p_instance->equAddr;
  232. tx_buf[pos++] = 0x1A;
  233. tx_buf[pos++] = 0x01;
  234. tx_buf[pos++] = (c_battCap>>8)&0xFF;
  235. tx_buf[pos++] = c_battCap&0xFF;
  236. tx_buf[pos++] = (c_ActDischargeEndVolt>>8)&0xFF;
  237. tx_buf[pos++] = c_ActDischargeEndVolt&0xFF;
  238. tx_buf[pos++] = (c_BattLowCapAlarm>>8)&0xFF;
  239. tx_buf[pos++] = c_BattLowCapAlarm&0xFF;
  240. calc_sum = calcByteSum(tx_buf,pos);
  241. tx_buf[pos++] = calc_sum;
  242. addFrameToSendBuff(p_instance,tx_buf,pos);
  243. }
  244. static void processSend(COMM_POW_MOD *p_instance)
  245. {
  246. const DWORD c_readYxCycletimeSecond = 1; // 1s 单位:s
  247. const DWORD c_readRunInfoCycletimeSecond = 10; // 10s 单位:s
  248. if(g_signalFlag.BIT.wActStart){
  249. g_signalFlag.BIT.wActStart = FALSE;
  250. sendFixedFrame(p_instance,TX_WRITE_FUNC,0x01);
  251. }else if(g_signalFlag.BIT.wActStop){
  252. g_signalFlag.BIT.wActStop = FALSE;
  253. sendFixedFrame(p_instance,TX_WRITE_FUNC,0x02);
  254. }else if(g_signalFlag.BIT.wDischargeStop){
  255. g_signalFlag.BIT.wDischargeStop = FALSE;
  256. sendFixedFrame(p_instance,TX_WRITE_FUNC,0x03);
  257. }else if(g_signalFlag.BIT.cActData){
  258. g_signalFlag.BIT.cActData = FALSE;
  259. sendActInfoClearFrame(p_instance);
  260. }else if(g_signalFlag.BIT.rVolt){
  261. p_instance->readYxCount = ustimer_get_origin();
  262. g_signalFlag.BIT.rVolt = FALSE;
  263. sendFixedFrame(p_instance,TX_READ_FUNC,0x01);
  264. }else if(g_signalFlag.BIT.rStatus){
  265. p_instance->readYxCount = ustimer_get_origin();
  266. g_signalFlag.BIT.rStatus = FALSE;
  267. sendFixedFrame(p_instance,TX_READ_FUNC,0x02);
  268. }else if(g_signalFlag.BIT.rRunInfo){
  269. p_instance->readRunInfoCount = ustimer_get_origin();
  270. g_signalFlag.BIT.rRunInfo = FALSE;
  271. sendFixedFrame(p_instance,TX_READ_FUNC,0x03);
  272. }
  273. #ifdef BATTERY_BP_L500
  274. else if(g_signalFlag.BIT.rBattR)
  275. {
  276. p_instance->ReadBattRCount = ustimer_get_origin();
  277. g_signalFlag.BIT.rBattR = FALSE;
  278. sendFixedFrame(p_instance,TX_READ_FUNC,0x10);
  279. }
  280. else if(g_signalFlag.BIT.rBattTemp)
  281. {
  282. p_instance->ReadBattTempCount = ustimer_get_origin();
  283. g_signalFlag.BIT.rBattTemp = FALSE;
  284. sendFixedFrame(p_instance,TX_READ_FUNC,0x11);
  285. }
  286. else if(g_signalFlag.BIT.rBattRtPower)
  287. {
  288. p_instance->ReadBattRtPowerCount = ustimer_get_origin();
  289. g_signalFlag.BIT.rBattRtPower = FALSE;
  290. sendFixedFrame(p_instance,TX_READ_FUNC,0x12);
  291. }
  292. else if(g_signalFlag.BIT.rBatCurrent)
  293. {
  294. p_instance->BatCurrentCount = ustimer_get_origin();
  295. g_signalFlag.BIT.rBatCurrent = FALSE;
  296. sendFixedFrame(p_instance,TX_READ_FUNC,0x0D);
  297. }
  298. else if(g_signalFlag.BIT.wBattR)
  299. {
  300. //p_instance->DetectBattRCount = ustimer_get_origin();
  301. g_signalFlag.BIT.wBattR = FALSE;
  302. sendFixedFrame(p_instance,TX_WRITE_FUNC,0x0A);
  303. }
  304. if(ustimer_get_duration(p_instance->ReadBattRCount) > 500 * USTIMER_MS){
  305. g_signalFlag.BIT.rBattR = TRUE;
  306. }
  307. if(ustimer_get_duration(p_instance->ReadBattTempCount) > 1500 * USTIMER_MS){
  308. g_signalFlag.BIT.rBattTemp = TRUE;
  309. }
  310. if(ustimer_get_duration(p_instance->ReadBattRtPowerCount) > 2000 * USTIMER_MS){
  311. g_signalFlag.BIT.rBattRtPower = TRUE;
  312. }
  313. if(ustimer_get_duration(p_instance->BatCurrentCount) > 2500 * USTIMER_MS){
  314. g_signalFlag.BIT.rBatCurrent = TRUE;
  315. }
  316. #endif
  317. if(ustimer_get_duration(p_instance->readYxCount) > c_readYxCycletimeSecond * USTIMER_SEC){
  318. g_signalFlag.BIT.rStatus = TRUE;
  319. g_signalFlag.BIT.rVolt = TRUE;
  320. p_instance->sendMesgCount++;
  321. }
  322. if(p_instance->sendMesgCount > 60){
  323. p_instance->commFault = true;
  324. if(!soe_check(EV_DYSTATUS)){
  325. soe_record_ev(EV_DYSTATUS, 1, 0, 0, 0);
  326. }
  327. }
  328. if(ustimer_get_duration(p_instance->readRunInfoCount) > c_readRunInfoCycletimeSecond * USTIMER_SEC){
  329. g_signalFlag.BIT.rRunInfo = TRUE;
  330. }
  331. #ifdef BATTERY_BP_L500
  332. if(ustimer_get_duration(p_instance->DetectBattRCount) > (180 * USTIMER_SEC))
  333. {
  334. g_signalFlag.BIT.wBattR = TRUE;
  335. rt_printf_time("启动电池内阻检测..\r\n");
  336. p_instance->DetectBattRCount = ustimer_get_origin();
  337. }
  338. #endif
  339. }
  340. void ClearBattActInfo(void)
  341. {
  342. g_signalFlag.BIT.cActData = TRUE;
  343. }
  344. void StartBattAct(void)
  345. {
  346. g_signalFlag.BIT.wActStart = TRUE;
  347. }
  348. void StopBattAct(void)
  349. {
  350. g_signalFlag.BIT.wActStop = TRUE;
  351. }
  352. void PowerModuleCommInit(COMM_POW_MOD *p_instance,int ch)
  353. {
  354. memset(&g_signalFlag, 0, sizeof(SIGNAL_FLG));
  355. memset(p_instance, 0, sizeof(COMM_POW_MOD));
  356. p_instance->equAddr = 1;
  357. p_instance->portChannel = ch;
  358. }
  359. void PowerModuleCommRecv(COMM_POW_MOD *p_instance,BYTE rec_data)
  360. {
  361. p_instance->recvBuf[p_instance->recvPos] = rec_data;
  362. p_instance->recvPos = (p_instance->recvPos + 1) % RX_BUF_SIZE_MAX;
  363. switch(p_instance->recvFlg){
  364. case 0:
  365. p_instance->dataLen = 0;
  366. p_instance->recvCount = 0;
  367. if(rec_data == c_frameStartByte_1){
  368. p_instance->recvFlg = 1;
  369. }
  370. break;
  371. case 1:
  372. if(rec_data == c_frameStartByte_2){
  373. p_instance->recvFlg = 2;
  374. }else{
  375. p_instance->recvFlg = 0;
  376. }
  377. break;
  378. case 2:
  379. p_instance->dataLen = rec_data;
  380. p_instance->recvFlg = 3;
  381. break;
  382. case 3:
  383. if(++p_instance->recvCount >= p_instance->dataLen){
  384. p_instance->recvFlg = 4;
  385. }
  386. break;
  387. case 4:
  388. p_instance->recvFlg = 0;
  389. p_instance->bData = true;
  390. break;
  391. default:
  392. p_instance->recvFlg = 0;
  393. p_instance->bData = false;
  394. break;
  395. }
  396. }
  397. void PowerModuleCommRun(COMM_POW_MOD *p_instance)
  398. {
  399. processSend(p_instance);
  400. processRecv(p_instance);
  401. }
  402. #endif