Преглед изворни кода

update debounce

Signed-off-by: huhui <huhui@sharkgulf.com>
huhui пре 5 година
родитељ
комит
6a09ea1462
4 измењених фајлова са 117 додато и 54 уклоњено
  1. 88 48
      Application/app/sox/health.c
  2. 7 3
      Application/app/sox/health.h
  3. 3 0
      Application/bsp/gd32_adc.c
  4. 19 3
      Project/SP700.uvoptx

+ 88 - 48
Application/app/sox/health.c

@@ -12,6 +12,7 @@
 #define MIN_VOLTAGE_FOR_RECOVERY_DISCHARGER (2.3f * CELLS_NUM * 1000) //恢复放电的最小电压
 #define MIN_VOLTAGE_FOR_POWER_DOWN (2.1f * CELLS_NUM* 1000)
 #define SIGLE_CELL_LOWER_DISCHARGER_VOLTAGE (1820) //最小允许的电芯放电电压 1.8v, 考虑到采样的误差取 1.82
+
 #define SIGLE_CELL_MAX_CHARGER_VOLTAGE (3880)//最大允许充电电压,3.9v,考虑到采样的误差取 3.88
 
 static int8_t charger_normal_low_temp[PACK_TEMPS_NUM] = {0,0,0,0}; //正常的充电最低温度
@@ -24,6 +25,23 @@ static int8_t discharger_normal_high_temp[PACK_TEMPS_NUM] = {50,50,50,55};//
 static int8_t discharger_lower_low_temp[PACK_TEMPS_NUM] = {-15,-15,-15,-10}; //需要停止放电的最低温度
 static int8_t discharger_higher_high_temp[PACK_TEMPS_NUM] = {55,55,55,60};//需要停止放电的最高温度
 
+/*定义低温和正常温度下的电池保护参数, [0]低温参数, [1]常温参数 */
+/*能提供大电的最小电压*/
+static float min_discharger_vol[] = {(2100 * CELLS_NUM), (2300 * CELLS_NUM)};//允许能放电的最小电压
+static float min_discharger_recovery_vol[] = {(2200 * CELLS_NUM), (2400 * CELLS_NUM)};//恢复放电的最小电压
+static float min_discharger_cell_vol[] = {2100, 2300};//允许能放电的最小电芯电压
+static float min_discharger_cell_recovery_vol[] = {2200, 2400};//恢复放电的最小电芯电压
+
+/*能提供动力的最小电压*/
+static float min_discharger_power_vol[] = {(2100 * CELLS_NUM), (2300 * CELLS_NUM)}; //允许能提供动力的最小电压
+static float min_discharger_power_recovery_vol[] = {(2100 * CELLS_NUM), (2300 * CELLS_NUM)}; //恢复能提供动力的最小电压
+static float min_discharger_power_cell_vol[] = {2100, 2300}; //允许能提供动力的最小电芯电压
+static float min_discharger_power_recovery_cell_vol[] = {2100, 2300}; //恢复能提供动力的最小电芯电压
+
+/*电池PowerDown的最小电压 */
+static float min_discharger_pdown_vol[] = {(2000 * CELLS_NUM), (2300 * CELLS_NUM)}; //power down的最小电压
+static float min_discharger_pdown_cell_vol[] = {1900, 2200};                        //power down的最小电芯电压
+
 /* health 模块,只检测状态,不做任何控制,如果有异常情况,控制中心会统一处理  */
 static void check_ml5238_state(int event);
 static void init_detect_timer(void);
@@ -39,6 +57,7 @@ void health_init(void){
 	init_detect_timer();
 	set_log_level(MOD_HEALTH, L_debug);
 	_health.internal_resistance = 20; //毫欧,暂时用一个固定数据,后期需要计算R0=(U2-U1)/(I1-I2) - R1(R1为电路上的等效电阻+采样电阻)
+	_health.is_work_temp_lower = 1;
 }
 
 bms_health_t *bms_health(){
@@ -128,85 +147,106 @@ void check_current_state(void){
 }
 
 /* 检测pack电压,cell电压,pack电压过低触发powerdown*/
-static debounce_t _discharger_lower_voltage = {.count = 10, .max_count = 20, .init_count = 10};
+static debounce_t _discharger_lower_voltage = {.count = 0, .max_count = 20, .init_count = 10};
 static debounce_t _power_down_voltage = {.count = 0, .max_count = 10, .init_count = 0};
-static debounce_t _sigle_cell_discharger_lower_vol = {.count = 5, .max_count = 10, .init_count = 5};
-static debounce_t _sigle_cell_charger_max_vol = {.count = 15, .max_count = 30, .init_count = 15};
+static debounce_t _sigle_cell_discharger_lower_vol = {.count = 0, .max_count = 10, .init_count = 5};
+static debounce_t _sigle_cell_charger_max_vol = {.count = 0, .max_count = 30, .init_count = 15};
+static debounce_t _shut_discharger_lower_voltage = {.count = 0, .max_count = 20,};
+static debounce_t _shut_discharger_cell_lower_voltage = {.count = 0, .max_count = 20,};
+
+static int judge_debounce(int input, debounce_t *d){
+	if (input) {
+		d->count ++;
+		if (d->count >= d->max_count){
+			d->count = 0;
+			return 1;
+		}
+		return 0;
+	}else {
+		d->count = d->init_count;
+		return 0;
+	}
+}
+
+static int _can_powerdown(void){
+	if (io_state()->charger_detect || bms_state_get()->charging){
+		return 0;
+	}
+	if ((bms_state_get()->pack_voltage <= min_discharger_pdown_vol[_health.is_work_temp_lower] ||
+			bms_state_get()->cell_min_vol <= min_discharger_pdown_cell_vol[_health.is_work_temp_lower])){
+		return 1;
+	}
+	return 0;
+}
+
 
 void check_voltage_state(void) {
 	if (bms_state_get()->charging){ //check sigle cell's voltage for charger
-		if ((bms_state_get()->cell_max_vol>= SIGLE_CELL_MAX_CHARGER_VOLTAGE) && !_health.sigle_cell_over_voltage){
-			debounce_inc(_sigle_cell_charger_max_vol);
-			if (debounce_reach_max(_sigle_cell_charger_max_vol)){
+		if ((bms_state_get()->cell_max_vol>= SIGLE_CELL_MAX_CHARGER_VOLTAGE)){
+			if (judge_debounce(!_health.sigle_cell_over_voltage, &_sigle_cell_charger_max_vol)){
 				_health.sigle_cell_over_voltage = 1;
-				debounce_reset(_sigle_cell_charger_max_vol);
 			}
-		}else if ((bms_state_get()->cell_max_vol < SIGLE_CELL_MAX_CHARGER_VOLTAGE) && _health.sigle_cell_over_voltage){
-			debounce_dec(_sigle_cell_charger_max_vol);
-			if (debounce_reach_zero(_sigle_cell_charger_max_vol)){
+		}else if ((bms_state_get()->cell_max_vol < SIGLE_CELL_MAX_CHARGER_VOLTAGE)){
+			if (judge_debounce(_health.sigle_cell_over_voltage, &_sigle_cell_charger_max_vol)){
 				_health.sigle_cell_over_voltage = 0;
-				debounce_reset(_sigle_cell_charger_max_vol);
 			}
 		}
 	}else{ 
 		//check sigle cell's voltage for discharger
-		if ((bms_state_get()->cell_min_vol <= SIGLE_CELL_LOWER_DISCHARGER_VOLTAGE) && !_health.sigle_cell_lower_voltage){
-			debounce_inc(_sigle_cell_discharger_lower_vol);
-			if (debounce_reach_max(_sigle_cell_discharger_lower_vol)){
+		if ((bms_state_get()->cell_min_vol <= min_discharger_cell_vol[_health.is_work_temp_lower])){
+			if (judge_debounce(!_health.sigle_cell_lower_voltage, &_sigle_cell_discharger_lower_vol)){
 				_health.sigle_cell_lower_voltage = 1;
-				debounce_reset(_sigle_cell_discharger_lower_vol);
 			}
-		}else if ((bms_state_get()->cell_min_vol > SIGLE_CELL_LOWER_DISCHARGER_VOLTAGE) && _health.sigle_cell_lower_voltage){
-			debounce_dec(_sigle_cell_discharger_lower_vol);
-			if (debounce_reach_zero(_sigle_cell_discharger_lower_vol)){
+		}else if ((bms_state_get()->cell_min_vol >= min_discharger_cell_recovery_vol[_health.is_work_temp_lower])){
+			if (judge_debounce(_health.sigle_cell_lower_voltage, &_sigle_cell_discharger_lower_vol)){
 				_health.sigle_cell_lower_voltage = 0;
-				debounce_reset(_sigle_cell_discharger_lower_vol);
 			}
 		}
 		//check sigle pack's voltage for discharger
-		if (!_health.discharger_lower_voltage){ //check for low pack voltage for close discharger
-			if (bms_state_get()->pack_voltage <= MIN_VOLTAGE_FOR_DISCHARGER){
-				debounce_inc(_discharger_lower_voltage);
-			}else {
-				debounce_reset(_discharger_lower_voltage);
-			}
-			if (debounce_reach_max(_discharger_lower_voltage)){
+		if (bms_state_get()->pack_voltage <= min_discharger_vol[_health.is_work_temp_lower]){
+			if (judge_debounce(!_health.discharger_lower_voltage, &_discharger_lower_voltage)){
 				_health.discharger_lower_voltage = 1;
-				debounce_reset(_discharger_lower_voltage);
-			}
-
-		}else { //check for discharger recovery
-			if (bms_state_get()->pack_voltage >= MIN_VOLTAGE_FOR_RECOVERY_DISCHARGER){
-				debounce_inc(_discharger_lower_voltage);
-			}else {
-				debounce_reset(_discharger_lower_voltage);
 			}
-			if (debounce_reach_max(_discharger_lower_voltage)){
+		}else if (bms_state_get()->pack_voltage >= min_discharger_recovery_vol[_health.is_work_temp_lower]){
+			if (judge_debounce(_health.discharger_lower_voltage, &_discharger_lower_voltage)){
 				_health.discharger_lower_voltage = 0;
-				debounce_reset(_discharger_lower_voltage);
-			}		
+			}
+		}
+		//check for shutdown power
+		if ((bms_state_get()->cell_min_vol <= min_discharger_power_cell_vol[_health.is_work_temp_lower])){
+			if (judge_debounce(!_health.discharger_cell_shutpower_voltage, &_shut_discharger_cell_lower_voltage)){
+				_health.discharger_cell_shutpower_voltage = 1;
+			}
+		}else if ((bms_state_get()->cell_min_vol >= min_discharger_power_recovery_cell_vol[_health.is_work_temp_lower])){
+			if (judge_debounce(_health.discharger_cell_shutpower_voltage, &_shut_discharger_cell_lower_voltage)){
+				_health.discharger_cell_shutpower_voltage = 0;
+			}
+		}
+		if ((bms_state_get()->cell_min_vol <= min_discharger_power_vol[_health.is_work_temp_lower])){
+			if (judge_debounce(!_health.discharger_cell_shutpower_voltage, &_shut_discharger_lower_voltage)){
+				_health.discharger_shutpower_voltage = 1;
+			}
+		}else if ((bms_state_get()->cell_min_vol >= min_discharger_power_recovery_vol[_health.is_work_temp_lower])){
+			if (judge_debounce(_health.discharger_cell_shutpower_voltage, &_shut_discharger_lower_voltage)){
+				_health.discharger_shutpower_voltage = 0;
+			}
 		}		
 	}	
 
 	/* check for power down */
-	if (!io_state()->charger_detect && !bms_state_get()->charging && !_health.powerdown_lower_voltage){
-		if (bms_state_get()->pack_voltage <= MIN_VOLTAGE_FOR_POWER_DOWN){
-			debounce_inc(_power_down_voltage);
-		}else {
-			debounce_reset(_power_down_voltage);
-		}
-		if (debounce_reach_max(_power_down_voltage)){
+	if (_can_powerdown()){
+		if (judge_debounce(!_health.powerdown_lower_voltage, &_power_down_voltage)) {
 			/*
 			 * no need to clear powerdown(bms is shutdown), when charger insert, 
 			 * system will power on with powerdown_lower_voltage cleared
-			*/
-			_health.powerdown_lower_voltage = 1; 
-			debounce_reset(_power_down_voltage);
-		}	
+			*/			
+			_health.powerdown_lower_voltage = 1;
+		}
 	}
 	debug_health();
 }
 
+
 /* 检测温度情况,看是否过高温,或者过低温 */
 
 static debounce_t _charger_over_temp      = {.count = 0, .max_count = 10, .init_count = 0};

+ 7 - 3
Application/app/sox/health.h

@@ -8,7 +8,7 @@
 */
 typedef struct {
 	uint32_t charger_over_voltage:1;
-	uint32_t discharger_lower_voltage:1;
+	uint32_t discharger_lower_voltage:1; //关闭大电流输出
 	uint32_t small_current_short:1;
 	uint32_t load_current_short:1; //大电短路保护
 
@@ -27,10 +27,14 @@ typedef struct {
 	uint32_t charger_over_temp:1;
 	uint32_t discharger_over_temp:1;
 
-	uint32_t sigle_cell_lower_voltage:1;
+	uint32_t sigle_cell_lower_voltage:1; //关闭大电流输出
 	uint32_t sigle_cell_over_voltage:1;
 
-	uint32_t res2:14;
+	uint32_t discharger_shutpower_voltage:1; //关闭动力
+	uint32_t discharger_cell_shutpower_voltage:1; //关闭动力
+	
+	uint32_t is_work_temp_lower:1;
+	uint32_t res2:11;
 	uint16_t internal_resistance;   //pack's internal resistance
 }bms_health_t;
 

+ 3 - 0
Application/bsp/gd32_adc.c

@@ -236,6 +236,9 @@ int adc_sample_avg(int chan, int times){
 		}
 	}
 	adc_disable();
+	if (times <= 2) {
+		return value/times;
+	}
 	return (value - min - max)/(times-2);
 }
 #endif /* DMA_ADC_CH */

+ 19 - 3
Project/SP700.uvoptx

@@ -170,16 +170,32 @@
           <Type>0</Type>
           <LineNumber>202</LineNumber>
           <EnabledFlag>1</EnabledFlag>
-          <Address>134227076</Address>
+          <Address>0</Address>
           <ByteObject>0</ByteObject>
           <HtxType>0</HtxType>
           <ManyObjects>0</ManyObjects>
           <SizeOfObject>0</SizeOfObject>
           <BreakByAccess>0</BreakByAccess>
-          <BreakIfRCount>1</BreakIfRCount>
+          <BreakIfRCount>0</BreakIfRCount>
+          <Filename>..\Application\app\sox\health.c</Filename>
+          <ExecCommand></ExecCommand>
+          <Expression></Expression>
+        </Bp>
+        <Bp>
+          <Number>2</Number>
+          <Type>0</Type>
+          <LineNumber>203</LineNumber>
+          <EnabledFlag>1</EnabledFlag>
+          <Address>0</Address>
+          <ByteObject>0</ByteObject>
+          <HtxType>0</HtxType>
+          <ManyObjects>0</ManyObjects>
+          <SizeOfObject>0</SizeOfObject>
+          <BreakByAccess>0</BreakByAccess>
+          <BreakIfRCount>0</BreakIfRCount>
           <Filename>..\Application\app\sox\health.c</Filename>
           <ExecCommand></ExecCommand>
-          <Expression>\\SP700\../Application/app/sox/health.c\202</Expression>
+          <Expression></Expression>
         </Bp>
       </Breakpoint>
       <WatchWindow1>