state.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #include "bsp/gpio.h"
  2. #include "bsp/ml5238.h"
  3. #include "app/sox/measure.h"
  4. #include "app/sox/measure_task.h"
  5. #include "libs/shark_task.h"
  6. #include "health.h"
  7. #include "state.h"
  8. #include "iostate.h"
  9. static bms_state_t _bms_state;
  10. static void _current_notify(void);
  11. static void _voltage_notify(void);
  12. static void _temperature_notify(void);
  13. void bms_state_init(void){
  14. _bms_state.cell_index_of_max_vol = 0xff;
  15. measure_task_init(_current_notify, _voltage_notify, _temperature_notify);
  16. io_state_init();
  17. health_init();
  18. }
  19. bms_state_t *bms_state_get(void){
  20. return &_bms_state;
  21. }
  22. static debounce_t _charging_detect = {.count = 0, .max_count = 10};
  23. static void check_charging(){
  24. if (bms_health()->charger_over_current || bms_health()->load_current_short) {
  25. ml5238_enable_discharger_mosfet(0);
  26. ml5238_enable_charger_mosfet(0); //disable charger mosfet
  27. _bms_state.charging = 0;
  28. return;
  29. }
  30. if (!_bms_state.charging) {
  31. if (measure_value()->load_current >= MIN_START_CHARGER_CURRENT) {
  32. debounce_inc(_charging_detect);
  33. }else {
  34. debounce_reset(_charging_detect);
  35. }
  36. if (debounce_reach_max(&_charging_detect)){
  37. _bms_state.charging = 1;
  38. _bms_state.discharging = 0;
  39. debounce_reset(_charging_detect);
  40. }
  41. }else {
  42. if (measure_value()->load_current <= MIN_START_LOADING_CURRENT) {
  43. debounce_inc(_charging_detect);
  44. }else {
  45. debounce_reset(_charging_detect);
  46. }
  47. if (debounce_reach_max(_charging_detect)){
  48. _bms_state.charging = 0;
  49. _bms_state.discharging = 1;
  50. debounce_reset(_charging_detect);
  51. }
  52. }
  53. }
  54. static void _current_notify(void){
  55. check_current_state(); //check health of current
  56. check_charging();
  57. }
  58. /* 充电电流小于一定值,认为充满的时候,需要检查电芯的电压,如果发现有电芯电压过高,需要开启被动均衡
  59. * 充电过程中考虑balance,主要是希望cell 电压扩散后,保证1. 单电芯不能过压, 2. 单电芯不能比平均电压过低,导致
  60. * 木桶效应,目标是电压最高的那个cell,尽量压制,不让电压再升高,或者升高的尽量慢一些
  61. */
  62. static debounce_t _cell_balance = {.count = 10, .max_count = 20};
  63. static void check_cell_balance(void){
  64. if (!_bms_state.charging){ //not charging, need not do balance
  65. if (_bms_state.pack_balancing){
  66. _bms_state.pack_balancing = 0;
  67. _cell_balance.count = 10;
  68. ml5238_cell_start_balance(0);
  69. }
  70. return;
  71. }
  72. if (_bms_state.cell_max_vol - _bms_state.cell_min_vol >= MAX_DIFF_BETWEEN_MIN_MAX_CELL){
  73. debounce_inc(_cell_balance);
  74. }else {
  75. debounce_dec(_cell_balance);
  76. }
  77. if (!_bms_state.pack_balancing && debounce_reach_max(_cell_balance)){
  78. _bms_state.pack_balancing = 1;
  79. }else if (_bms_state.pack_balancing && debounce_reach_zero(_cell_balance)){
  80. _bms_state.pack_balancing = 0;
  81. ml5238_cell_start_balance(0);
  82. }
  83. }
  84. static void _voltage_notify(void){
  85. uint16_t voltage = 0;
  86. uint16_t max_cell = 0;
  87. uint16_t min_cell = 0xf000;
  88. uint8_t max_index = 0;
  89. for (int i = 0; i < CELLS_NUM; i++){
  90. voltage += measure_value()->cell_vol[i];
  91. if (max_cell > measure_value()->cell_vol[i]){
  92. max_cell = measure_value()->cell_vol[i];
  93. max_index = i;
  94. }
  95. if (min_cell < measure_value()->cell_vol[i]){
  96. min_cell = measure_value()->cell_vol[i];
  97. }
  98. }
  99. _bms_state.pack_voltage = voltage;
  100. _bms_state.cell_max_vol = max_cell;
  101. _bms_state.cell_min_vol = min_cell;
  102. check_voltage_state(); //check health of cell voltage
  103. check_cell_balance();
  104. if (_bms_state.pack_balancing && (max_index != _bms_state.cell_index_of_max_vol)){
  105. ml5238_cell_start_balance(BIT(max_index));
  106. }
  107. _bms_state.cell_index_of_max_vol = max_index;
  108. }
  109. static void _temperature_notify(void){
  110. check_temp_state(); //check health of cell/pcb temperature
  111. }