bms.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /*
  2. * @Description:
  3. 该bms协议主动上传,只需要解析即可
  4. 对外3个接口:
  5. 数据解析,存在结构体
  6. 对外提供结构体查询
  7. 在线计时
  8. Bug0020
  9. * @version:
  10. * @Author: Joe
  11. * @Date: 2021-11-13 13:23:14
  12. * @LastEditTime: 2021-11-13 18:30:31
  13. */
  14. #include "bms.h"
  15. #include "string.h"
  16. #include "tfmini.h"
  17. #define DBG_TAG "bms"
  18. #define DBG_LVL DBG_INFO
  19. #include <rtdbg.h>
  20. #define CRC_16_POLYNOMIALS 0xA001
  21. static Battery_TypeDef bat = {0};
  22. /************************维旭电池****************************/
  23. uint8_t bms_parse(struct rt_can_msg *msg) //数据解析
  24. {
  25. uint8_t temp = 1;
  26. if(msg->ide!=RT_CAN_EXTID) //扩展帧
  27. return temp;
  28. temp = 0;
  29. bat.enable = 1;
  30. bat.miss_cnt = 0;
  31. switch(msg->id) /*解析数据*/
  32. {
  33. case 0xA6D0D09: //高压信息
  34. {
  35. bat.voltage = msg->data[0]<<8 | msg->data[1];
  36. bat.current = msg->data[2]<<8 | msg->data[3];
  37. }
  38. break;
  39. case 0xA6E0D09: //电量信息
  40. {
  41. bat.rsoc = (msg->data[0]<<8 | msg->data[1])/10; //%
  42. bat.current = msg->data[2]<<8 | msg->data[3];
  43. }
  44. break;
  45. case 0xAB40D09: //故障信息
  46. {
  47. bat.protect_status = msg->data[0]<<24 | msg->data[1]<<16 | msg->data[2]<<8 | msg->data[3];
  48. }
  49. break;
  50. default:
  51. break;
  52. }//数据解析
  53. return temp;
  54. }
  55. /************************奥冠电池****************************/
  56. /****************************************
  57. 函数功能 : 计算info字节长度校验项
  58. 参数描述 :
  59. 返回值 : 校验码,hex
  60. ****************************************/
  61. static uint16_t ag_bms_crc16(uint8_t* pchMsg,uint8_t wDataLen)
  62. {
  63. uint8_t i, chChar;
  64. uint16_t wCRC = 0xFFFF;
  65. while (wDataLen--)
  66. {
  67. chChar = *pchMsg++;
  68. wCRC ^= (uint16_t) chChar;
  69. for (i = 0; i < 8; i++)
  70. {
  71. if (wCRC & 0x0001)
  72. wCRC = (wCRC >> 1) ^ CRC_16_POLYNOMIALS;
  73. else
  74. wCRC >>= 1;
  75. }
  76. }
  77. return wCRC;
  78. }
  79. uint8_t ag_bms_parse(struct rt_can_msg *msg) //数据解析
  80. {
  81. uint8_t temp = 1;
  82. uint16_t chksum;
  83. if(msg->id != 0x101 || msg->rtr != RT_CAN_DTR) /* 地址为0x101,返回值为数据帧 */
  84. return temp;
  85. //CRC-16校验
  86. chksum = ag_bms_crc16((uint8_t*)msg->data,(msg->len-2));
  87. if( msg->data[msg->len-2]!=(chksum >> 8) || msg->data[msg->len-1]!=(chksum & 0x00FF))
  88. return temp;
  89. temp = 0;
  90. bat.enable = 1;
  91. //充满容量、循环次数、RSOC
  92. bat.rsoc = msg->data[4]<<8 | msg->data[5];
  93. return temp;
  94. }
  95. /****************************************
  96. * 查询bms数据
  97. *函数功能 :
  98. *参数描述 : 无
  99. *返回值 : 返回发送的can结构体
  100. ****************************************/
  101. struct rt_can_msg require_ag_bms_msg(void)
  102. {
  103. struct rt_can_msg tx_msg;
  104. tx_msg.id = 0x101;
  105. tx_msg.ide = RT_CAN_STDID; /* 标准格式 */
  106. tx_msg.rtr = RT_CAN_RTR; /* 遥控帧 */
  107. tx_msg.len = 1; /* 数据长度为 1 */
  108. /* 返回发送的can结构体 */
  109. return tx_msg;
  110. }
  111. uint16_t get_bat_rsoc(void)
  112. {
  113. return bat.rsoc;
  114. }
  115. uint8_t get_bat_enable(void)
  116. {
  117. return bat.enable;
  118. }
  119. /****************************************
  120. * get
  121. *函数功能 : 获取状态
  122. *参数描述 : 无
  123. *返回值 : 无
  124. ****************************************/
  125. int get(int argc, char **argv)
  126. {
  127. const char* help_info[] =
  128. {
  129. [0] = " get param - get machine param",
  130. [1] = " get bat - get battery param",
  131. [2] = " get tfmini - get tfmini param",
  132. };
  133. if (argc < 2)
  134. {
  135. LOG_I("Usage:");
  136. for (int i = 0; i < sizeof(help_info) / sizeof(char*); i++)
  137. {
  138. LOG_I("%s", help_info[i]);
  139. }
  140. }
  141. else
  142. {
  143. const char *operator = argv[1];
  144. if(!strcmp(operator, "bat"))
  145. {
  146. LOG_I("bat:enable[%d] rsoc[%d] current[%d] voltage[%s]", bat.enable,bat.rsoc,bat.current,bat.voltage);
  147. }
  148. else
  149. if(!strcmp(operator, "tfmini"))
  150. {
  151. TFMINI_TypeDef fmini;
  152. fmini = get_tfmini_for();
  153. LOG_I("tfmini_for:dist[%d] strength[%d]", fmini.dist,fmini.strength) ;
  154. fmini = get_tfmini_back();
  155. LOG_I("tfmini_back:dist[%d] strength[%d]", fmini.dist,fmini.strength) ;
  156. fmini = get_tfmini_left();
  157. LOG_I("tfmini_left:dist[%d] strength[%d]", fmini.dist,fmini.strength) ;
  158. fmini = get_tfmini_right();
  159. LOG_I("tfmini_right:dist[%d] strength[%d]", fmini.dist,fmini.strength) ;
  160. }
  161. }
  162. return 0;
  163. }
  164. MSH_CMD_EXPORT(get , get machine param);
  165. /****************************************
  166. * bat_init
  167. *函数功能 : 配置初始化
  168. *参数描述 : 无
  169. *返回值 : 无
  170. ****************************************/
  171. int bat_init(void)
  172. {
  173. bat.rsoc = 0;
  174. bat.enable = 0;
  175. return RT_EOK;
  176. }
  177. INIT_APP_EXPORT(bat_init);