Ver Fonte

1. 小电流短路判断加强,分保护和短路
2. 如果小电流短路,不能开大电

Signed-off-by: huhui <huhui@sharkgulf.com>

huhui há 5 anos atrás
pai
commit
0231f75637

+ 5 - 0
Application/app/sox/Least_Square.c

@@ -4,6 +4,10 @@
 //y = Kax + Cb
 //y = Kax + Cb
 void least_square_init(least_square_t *ls, int samples){
 void least_square_init(least_square_t *ls, int samples){
 	ls->max_samples = samples;
 	ls->max_samples = samples;
+	least_square_clear(ls);
+}
+
+void least_square_clear(least_square_t *ls) {
 	ls->num_samples = 0;
 	ls->num_samples = 0;
 	ls->coeff.Ka = 1.0f;
 	ls->coeff.Ka = 1.0f;
 	ls->coeff.Cb = 0.0f;
 	ls->coeff.Cb = 0.0f;
@@ -13,6 +17,7 @@ void least_square_init(least_square_t *ls, int samples){
 	ls->sum_y = 0;
 	ls->sum_y = 0;
 	ls->finished = 0;
 	ls->finished = 0;
 }
 }
+
 int least_square_put(least_square_t *ls, double x, double y){
 int least_square_put(least_square_t *ls, double x, double y){
 	if (!ls->finished){
 	if (!ls->finished){
 		ls->num_samples ++;
 		ls->num_samples ++;

+ 1 - 0
Application/app/sox/Least_Square.h

@@ -19,6 +19,7 @@ typedef struct {
 }least_square_t;
 }least_square_t;
 
 
 void least_square_init(least_square_t *ls, int samples);
 void least_square_init(least_square_t *ls, int samples);
+void least_square_clear(least_square_t *ls);
 int least_square_put(least_square_t *ls, double x, double y);
 int least_square_put(least_square_t *ls, double x, double y);
 double get_y_by_x(least_square_t *ls, double x);
 double get_y_by_x(least_square_t *ls, double x);
 int get_x_by_y(least_square_t *ls, double y);
 int get_x_by_y(least_square_t *ls, double y);

+ 24 - 30
Application/app/sox/health.c

@@ -6,6 +6,7 @@
 #include "measure.h"
 #include "measure.h"
 #include "measure_task.h"
 #include "measure_task.h"
 #include "health.h"
 #include "health.h"
+#include "Least_Square.h"
 
 
 #if 0
 #if 0
 #define MIN_VOLTAGE_FOR_DISCHARGER (2.2f * CELLS_NUM * 1000) //允许能放电的最小电压
 #define MIN_VOLTAGE_FOR_DISCHARGER (2.2f * CELLS_NUM * 1000) //允许能放电的最小电压
@@ -41,6 +42,8 @@ static float min_discharger_cell_recovery_vol[] = {2100, 2600};//
 static float min_discharger_pdown_vol[] = {28000, 34000}; //power down的最小电压
 static float min_discharger_pdown_vol[] = {28000, 34000}; //power down的最小电压
 static float min_discharger_pdown_cell_vol[] = {1900, 2200};                        //power down的最小电芯电压
 static float min_discharger_pdown_cell_vol[] = {1900, 2200};                        //power down的最小电芯电压
 
 
+#define MAX_TRY_FOR_AUX_SHORT 10
+
 /* health 模块,只检测状态,不做任何控制,如果有异常情况,控制中心会统一处理  */
 /* health 模块,只检测状态,不做任何控制,如果有异常情况,控制中心会统一处理  */
 static void check_ml5238_state(int event);
 static void check_ml5238_state(int event);
 static void load_detect_handler(shark_timer_t *timer);
 static void load_detect_handler(shark_timer_t *timer);
@@ -54,7 +57,6 @@ static bms_health_t _health;
 static debounce_timer_t _load_detect_timer = {.max_count = 100, .interval = 10, ._timer.handler = load_detect_handler};
 static debounce_timer_t _load_detect_timer = {.max_count = 100, .interval = 10, ._timer.handler = load_detect_handler};
 static debounce_timer_t _charger_detect_timer = {.max_count = 500, .interval = 10, ._timer.handler = charger_detect_handler};
 static debounce_timer_t _charger_detect_timer = {.max_count = 500, .interval = 10, ._timer.handler = charger_detect_handler};
 static shark_timer_t _clear_short_current_timer = {.handler = clear_short_current_handler};
 static shark_timer_t _clear_short_current_timer = {.handler = clear_short_current_handler};
-
 static error_counts_t error_counts;
 static error_counts_t error_counts;
 
 
 void health_init(void){
 void health_init(void){
@@ -72,6 +74,7 @@ void health_log(void){
 	health_debug("soft short:%d\n", error_counts.soft_current_short);
 	health_debug("soft short:%d\n", error_counts.soft_current_short);
 	health_debug("hard short:%d\n", error_counts.hard_current_short);
 	health_debug("hard short:%d\n", error_counts.hard_current_short);
 	health_debug("work temp: %d\n", _health.is_work_temp_normal);
 	health_debug("work temp: %d\n", _health.is_work_temp_normal);
+	health_debug("aux_short: %d, %d\n", error_counts.aux_short, error_counts.aux_real_short);
 }
 }
 
 
 bms_health_t *bms_health(){
 bms_health_t *bms_health(){
@@ -149,12 +152,7 @@ static debounce_t _charger_over_current = {
 	.count = 0,
 	.count = 0,
 	.max_count = 70
 	.max_count = 70
 };
 };
-#if 0
-static debounce_t _discharger_over_current = {
-	.count = 0,
-	.max_count = 20
-};
-#endif
+
 /* 55 - 100A, 14 - I x I / 750 */
 /* 55 - 100A, 14 - I x I / 750 */
 void check_current_state(void){
 void check_current_state(void){
 	float current = measure_value()->load_current;
 	float current = measure_value()->load_current;
@@ -183,20 +181,7 @@ void check_current_state(void){
 				ml5238_enable_load_detect(1); //打开负载检测
 				ml5238_enable_load_detect(1); //打开负载检测
 				shark_timer_post(&_load_detect_timer._timer, _load_detect_timer.interval);
 				shark_timer_post(&_load_detect_timer._timer, _load_detect_timer.interval);
 				soft_current_init();
 				soft_current_init();
-			}
-#if 0			
-			if ((abs(current) >= MAX_CURRENT_FOR_DISCHARGER)) {
-				_discharger_over_current.count++;
-			}else {
-				_discharger_over_current.count = 0;
-			}
-			if (_discharger_over_current.count >= _discharger_over_current.max_count) {
-				_health.load_current_short = 1;
-				_discharger_over_current.count = 0;
-				ml5238_enable_load_detect(1); //打开负载检测
-				shark_timer_post(&_load_detect_timer._timer, _load_detect_timer.interval);
-			}
-#endif			
+			}		
 		}
 		}
 	}	
 	}	
 }
 }
@@ -346,19 +331,26 @@ static shark_timer_t _aux_unlock_timer = {.handler = _aux_unlock_timer_handler};
 
 
 static void _aux_lock_timer_handler(shark_timer_t *t){
 static void _aux_lock_timer_handler(shark_timer_t *t){
 	AUX_VOL_OPEN(1);
 	AUX_VOL_OPEN(1);
-	shark_timer_post( &_aux_unlock_timer, 200);
-	health_debug("open aux[re-enable], %lld\n", shark_get_mseconds());
-	if (++small_power_detect_count >= 10){
-		delay_us(1000);
+	if (++small_power_detect_count >= MAX_TRY_FOR_AUX_SHORT){
 		//端口电压小于阈值,判断为小电流短路
 		//端口电压小于阈值,判断为小电流短路
-		if (get_small_current_voltage() < SMALL_CURRENT_MIN_VOLTAGE){//real short
-			bms_health()->small_current_short = 1;
+		int short_voltage = get_small_current_voltage()/1000;
+		int pack_voltage = bms_state_get()->pack_voltage/1000;
+		if (short_voltage >= (pack_voltage - AUX_SHORT_DIFF_VOLTAGE)) {
+			_health.small_current_short = 1;
+			error_counts.aux_short ++;
 			AUX_VOL_OPEN(0);
 			AUX_VOL_OPEN(0);
 			small_power_detect_count = 0;
 			small_power_detect_count = 0;
 			shark_timer_post( &_aux_lock_timer, 30 * 1000); //30s后再次尝试打开
 			shark_timer_post( &_aux_lock_timer, 30 * 1000); //30s后再次尝试打开
 			shark_timer_cancel(&_aux_unlock_timer);
 			shark_timer_cancel(&_aux_unlock_timer);
-			health_debug("set aux short current, and retry after 30s\n");
+			if (short_voltage >= (pack_voltage - AUX_SHORT_REAL_DIFF_VOLTAGE)){ //real short
+				error_counts.aux_real_short ++;
+				_health.small_current_real_short = 1;
+			}
+			health_debug("aux short, v:%d, and retry after 30s\n", short_voltage);
 		}
 		}
+	}else {
+		health_debug("open aux[re-enable], %lld\n", shark_get_mseconds());
+		shark_timer_post( &_aux_unlock_timer, 200);
 	}
 	}
 }
 }
 
 
@@ -366,7 +358,8 @@ static void _aux_unlock_timer_handler(shark_timer_t *t){
 	if (!io_state()->aux_lock_detect){
 	if (!io_state()->aux_lock_detect){
 		health_debug("unlock aux detect\n");
 		health_debug("unlock aux detect\n");
 		small_power_detect_count = 0;
 		small_power_detect_count = 0;
-		bms_health()->small_current_short = 0;
+		_health.small_current_short = 0;
+		_health.small_current_real_short = 0;
 		AUX_VOL_OPEN(1);
 		AUX_VOL_OPEN(1);
 	}
 	}
 }
 }
@@ -375,7 +368,8 @@ static void _aux_unlock_timer_handler(shark_timer_t *t){
 void health_stop_aux_detect(void){
 void health_stop_aux_detect(void){
 	shark_timer_cancel(&_aux_unlock_timer);
 	shark_timer_cancel(&_aux_unlock_timer);
 	shark_timer_cancel(&_aux_lock_timer);
 	shark_timer_cancel(&_aux_lock_timer);
-	bms_health()->small_current_short = 0;
+	_health.small_current_short = 0;
+	_health.small_current_real_short = 0;
 }
 }
 
 
 void health_process_aux_lock(void){
 void health_process_aux_lock(void){

+ 9 - 4
Application/app/sox/health.h

@@ -6,6 +6,9 @@
 #define MAX_CURRENT_FOR_CHARGER (30*1000) //最大充电电流20A
 #define MAX_CURRENT_FOR_CHARGER (30*1000) //最大充电电流20A
 #define SIGLE_CELL_MAX_CHARGER_VOLTAGE (3800)//最大允许充电电压,3.9v,考虑到采样的误差取 3.88
 #define SIGLE_CELL_MAX_CHARGER_VOLTAGE (3800)//最大允许充电电压,3.9v,考虑到采样的误差取 3.88
 #define MAX_CURRENT_FOR_DISCHARGER (120 * 1000) //软件采样的电流保护
 #define MAX_CURRENT_FOR_DISCHARGER (120 * 1000) //软件采样的电流保护
+#define AUX_SHORT_REAL_DIFF_VOLTAGE (5) //判断小电流是否真实短路的,端口压差
+#define AUX_SHORT_DIFF_VOLTAGE (20) //判断小电流是否保护,端口压差
+
 /* 
 /* 
  * xxx_over_temp: 表示过高温(温度过高)
  * xxx_over_temp: 表示过高温(温度过高)
  * xxx_under_temp: 表示过低温(温度过低)
  * xxx_under_temp: 表示过低温(温度过低)
@@ -33,25 +36,27 @@ typedef struct {
 
 
 	uint32_t sigle_cell_lower_voltage:1; //关闭大电流输出
 	uint32_t sigle_cell_lower_voltage:1; //关闭大电流输出
 	uint32_t sigle_cell_over_voltage:1;
 	uint32_t sigle_cell_over_voltage:1;
-
 	uint32_t discharger_shutpower_voltage:1; //关闭动力
 	uint32_t discharger_shutpower_voltage:1; //关闭动力
 	uint32_t discharger_cell_shutpower_voltage:1; //关闭动力
 	uint32_t discharger_cell_shutpower_voltage:1; //关闭动力
+
 	
 	
 	uint32_t is_work_temp_normal:1;
 	uint32_t is_work_temp_normal:1;
-
 	uint32_t lower_temp_deny_charger:1;
 	uint32_t lower_temp_deny_charger:1;
 	uint32_t lower_temp_deny_discharger:1;
 	uint32_t lower_temp_deny_discharger:1;
 	uint32_t over_temp_deny_charger:1;
 	uint32_t over_temp_deny_charger:1;
+	
 	uint32_t over_temp_deny_discharger:1;
 	uint32_t over_temp_deny_discharger:1;
-
+	uint32_t small_current_real_short:1; //真实短路
 	
 	
-	uint32_t res2:11;
+	uint32_t res2:10;
 	uint8_t    internal_resistance[CELLS_NUM];   //cell's internal resistance
 	uint8_t    internal_resistance[CELLS_NUM];   //cell's internal resistance
 }bms_health_t;
 }bms_health_t;
 
 
 typedef struct {
 typedef struct {
 	uint32_t soft_current_short;
 	uint32_t soft_current_short;
 	uint32_t hard_current_short;
 	uint32_t hard_current_short;
+	uint32_t aux_short;
+	uint32_t aux_real_short;
 }error_counts_t;
 }error_counts_t;
 
 
 bms_health_t *bms_health(void);
 bms_health_t *bms_health(void);

+ 2 - 4
Application/app/sox/measure.c

@@ -46,7 +46,7 @@ static const float v_gd_ref = 3300.0f; //adc ref = 3.3v
 static const float max_gd_adc = 4095.0f;//65536.0f;
 static const float max_gd_adc = 4095.0f;//65536.0f;
 static const float v_cs1180_ref = 1235.0f;//cs1180 vref = 1.235v
 static const float v_cs1180_ref = 1235.0f;//cs1180 vref = 1.235v
 static const float max_cs1180_adc = 0x7FFFF;//
 static const float max_cs1180_adc = 0x7FFFF;//
-static const float small_cur_r_sense = 360.0f;//欧姆
+static const float small_cur_r_sense = 0.360f;//欧姆
 static least_square_t adc_cali[2]; // y = ax + b
 static least_square_t adc_cali[2]; // y = ax + b
 
 
 #define GD32_ADC_READ_TIMES 128
 #define GD32_ADC_READ_TIMES 128
@@ -189,15 +189,13 @@ float get_cell_voltage(int cell){
 
 
 /* get battery pack's aux current (MA) */
 /* get battery pack's aux current (MA) */
 float get_small_current(void){
 float get_small_current(void){
-	float adc = adc_sample_avg(ADC_CHAN_AUX_CURR, GD32_ADC_READ_TIMES);
-
+	float adc = adc_sample_avg(ADC_CHAN_AUX_CURR, 16);
 	return ((adc / max_gd_adc * v_gd_ref)) / small_cur_r_sense;
 	return ((adc / max_gd_adc * v_gd_ref)) / small_cur_r_sense;
 }
 }
 
 
 /* 用来判断小电流的情况下,电压小于某一个值认为小电流真正短路,比如16v*/
 /* 用来判断小电流的情况下,电压小于某一个值认为小电流真正短路,比如16v*/
 float get_small_current_voltage(void){
 float get_small_current_voltage(void){
 	float s_current_a = get_small_current();//MA
 	float s_current_a = get_small_current();//MA
-
 	return s_current_a * (small_cur_r_sense + 28.0f);//28欧姆是mos的D极两个56的并联
 	return s_current_a * (small_cur_r_sense + 28.0f);//28欧姆是mos的D极两个56的并联
 }
 }
 
 

+ 3 - 0
Application/app/sox/state.c

@@ -241,6 +241,9 @@ static s32 _process_unheath(void){
 	}
 	}
 	if (io_state()->aux_lock_detect || bms_health()->small_current_short) {
 	if (io_state()->aux_lock_detect || bms_health()->small_current_short) {
 		unhealth |= Health_aux_Fault;
 		unhealth |= Health_aux_Fault;
+		if (bms_health()->small_current_real_short) {
+			unhealth |= Health_Discharger_Failt;
+		}
 	}
 	}
 	
 	
 	return unhealth;
 	return unhealth;

+ 0 - 1
Application/app/sox/state.h

@@ -20,7 +20,6 @@
 #define MIN_DIFF_BETWEEN_MIN_MAX_CELL 050 //0.05v, 牙差低于这个数据,停止balance
 #define MIN_DIFF_BETWEEN_MIN_MAX_CELL 050 //0.05v, 牙差低于这个数据,停止balance
 #define MAX_CELL_VOLTAGE_FOR_BALACNE 3700
 #define MAX_CELL_VOLTAGE_FOR_BALACNE 3700
 #define CELL_FUSION_VOLTAGE      3500 //LFP电池在3.5v的时候,开始发散,需要判断是否要balance
 #define CELL_FUSION_VOLTAGE      3500 //LFP电池在3.5v的时候,开始发散,需要判断是否要balance
-#define SMALL_CURRENT_MIN_VOLTAGE (16.0f * 1000.0f) //判断小电流是否真实短路的,端口最小电压
 
 
 
 
 typedef struct{
 typedef struct{