Просмотр исходного кода

1. 温度采集adc读取8次(以前一次)
2. cs1180和ML5238相差很大的时候,以5238为准,同时重新初始化cs1180
3. 低温放电根据不同的温度调整放电倍率

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

huhui 5 лет назад
Родитель
Сommit
0f9433bb1e

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

@@ -202,7 +202,7 @@ float get_small_current_voltage(void){
 int get_pcb_temperature(void){
 	TEMP_OPEN(1);
 	delay_us(100);
-	uint16_t adc = adc_sample_avg(ADC_CHAN_TEMPERATURE_4, 1);
+	uint16_t adc = adc_sample_avg(ADC_CHAN_TEMPERATURE_4, 8);
 	TEMP_OPEN(0);
 	return get_temp_by_adc(adc);
 }
@@ -213,7 +213,7 @@ int get_pcb_temperature(void){
 int get_pack_temperature(int index){
 	TEMP_OPEN(1);
 	delay_us(100);
-	uint16_t adc = adc_sample_avg(ADC_CHAN_TEMPERATURE_1 + index, 1);
+	uint16_t adc = adc_sample_avg(ADC_CHAN_TEMPERATURE_1 + index, 8);
 	TEMP_OPEN(0);
 	return get_temp_by_adc((adc<<4)&0xFFFF);
 }

+ 54 - 12
Application/app/sox/soc.c

@@ -18,7 +18,8 @@ static float     max_soc_delta_time = 0;
 static float _charger_coefficient = 1.0f;
 static float _discharger_coefficient = 1.0f;
 uint32_t charger_remain_time = 0;
-
+uint8_t battery_temp_state = 0;
+static const float _discharger_gain[] = {1.0f/*>0度*/, 1.002f/*-2<t<=0*/, 1.005f/*-5<t<=-2*/, 1.008f/*-10<t<=-5*/, 1.02f/*-15<t<=-10*/, 1.04f/*-20<t<=-15*/};
 #define MAX_TIME_FULL_TO_EMPTY (5 * 24 * 3600) //充满到欠压5天内达到,可以校准最小电量
 #define DEFALUT_MAX_COULOMB (MAX_HA * 3600.0f)
 #define DEFALUT_MIN_COULOMB (25.0f * 3600.0f)
@@ -59,6 +60,46 @@ void soc_init(void){
 	soc_log();
 }
 
+void soc_restore_by_iap(uint8_t flags, uint8_t capaticy){
+	_soc.coulomb_min = 0;
+	_soc.coulomb_max = DEFALUT_MAX_COULOMB; //30HA,这个值最总需要soh模块给
+	_soc.flags = 0;
+	_soc.charger_coulomb = 0;
+	_soc.pre_charger_coulomb = 0;
+	_soc.dischrger_coulomb = 0;
+	_soc.pre_discharger_coulomb = 0;
+	_soc.total_coulomb = 0;
+	if (flags == 1) {
+		_soc.flags |= SOC_FLAG_CALIBRATED;
+	}
+	_soc.capacity = capaticy;
+	_soc.coulomb_now = (_soc.coulomb_max - _soc.coulomb_min) * _soc.capacity / 100.0f + _soc.coulomb_min;
+	nv_save_all_soc();
+}
+
+static void soc_jugde_temp(void){
+	int low_temp = 0xFFFF;
+	for (int i = 0; i < PACK_TEMPS_NUM-1; i++) {
+		low_temp = MIN(low_temp, measure_value()->pack_temp[i]);
+	}
+	if (low_temp > 0) {
+		_discharger_coefficient = _discharger_gain[0];
+	}else {
+		if (low_temp > -2) {
+			_discharger_coefficient = _discharger_gain[1];
+		}else if (low_temp > -5) {
+			_discharger_coefficient = _discharger_gain[2];
+		}else if (low_temp > -10) {
+			_discharger_coefficient = _discharger_gain[3];
+		}else if (low_temp > -15) {
+			_discharger_coefficient = _discharger_gain[4];
+		}else {
+			_discharger_coefficient = _discharger_gain[5];
+		}
+		force_full_ts = 0xFFFFFFFF;
+	}
+}
+
 #if LEAST_SQUARE==1
 static void start_least_square(int start){
 	if (start && !least_square_started) {
@@ -109,6 +150,7 @@ void soc_log(void){
 	soc_debug("C tol: %.2f\n", _soc.total_coulomb);
 	soc_debug("C energy: %f\n", _soc.energy);
 	soc_debug("C delta time %f,%f, -- %d\n", max_soc_delta_time, soc_delta_time, force_full_ts);
+	soc_debug("C discharger coefficient = %f\n", _discharger_coefficient);
 	if (chargering){
 		soc_debug("C remain %d\n", charger_remain_time);
 	}
@@ -191,18 +233,16 @@ static int _soc_update_by_ocv(uint8_t prev_charge_status){
 		return 0;
 	}
 	if (!chargering){
-		if (bms_health()->is_work_temp_normal) {
-			if (_soc.capacity && _soc_is_under_voltage()) {
-				soc_warning("judge calib min col %d - %d\n", shark_get_seconds(), force_full_ts);
-				if (can_modify_min_cap()){
-					_soc.coulomb_min = _soc.coulomb_now; //已经校准过了,而且电池在常温下进入powerdown,最小容量修正为当前容量
-					soc_warning("calicablite coulomb_min %f\n", _soc.coulomb_min);
-				}else {
-					_soc.coulomb_now = _soc.coulomb_min;
-				}
-				_soc.capacity = 0;
-				return 1;
+		if (_soc.capacity && _soc_is_under_voltage()) {
+			soc_warning("judge calib min col %d - %d\n", shark_get_seconds(), force_full_ts);
+			if (can_modify_min_cap()){
+				_soc.coulomb_min = _soc.coulomb_now; //已经校准过了,而且电池在常温下进入powerdown,最小容量修正为当前容量
+				soc_warning("calicablite coulomb_min %f\n", _soc.coulomb_min);
+			}else {
+				_soc.coulomb_now = _soc.coulomb_min;
 			}
+			_soc.capacity = 0;
+			return 1;
 		}
 	}
 	if (chargering || prev_charge_status) {
@@ -309,6 +349,7 @@ static void soc_update_by_current_and_time(float current_now, float delta_time,
 			update_capticy = 1;
 		}
 	}else {
+		soc_jugde_temp();
 		delta_q = delta_q * _discharger_coefficient;
 		_soc.dischrger_coulomb += abs(delta_q);
 		if ((est_capaticy > 0) && (est_capaticy <= _soc.capacity)) {  //放电,容量不能等于0,需要靠欠压或者PowerDown 矫正到0
@@ -355,6 +396,7 @@ static void soc_update_by_current_and_time(float current_now, float delta_time,
 /*休眠bms功耗 + 电芯自放电 28天 3% (28天1AH)*/
 void soc_update_for_deepsleep(float sleep_time){
 	soc_update_by_current_and_time(-(0.32f + 1000.0f/(24.f * 28.f)), sleep_time, 0); //休眠功耗310uA(300uA + 10uA固定消耗)
+	current_sample_ts = shark_get_mseconds(); //唤醒后复位采集时间,如果不采集会重复计算
 }
 
 void soc_update(void){

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

@@ -28,4 +28,5 @@ uint32_t soc_get_charger_remain_time(void);
 soc_t *get_soc(void);
 void soc_log(void);
 void soc_update_for_deepsleep(float sleep_time);
+void soc_restore_by_iap(uint8_t flags, uint8_t capaticy);
 

+ 10 - 1
Application/app/sox/state.c

@@ -1,5 +1,6 @@
 #include "bsp/gpio.h"
 #include "bsp/ml5238.h"
+#include "bsp/cs1180.h"
 #include "bsp/uart.h"
 #include "bsp/mcu_power_sleep.h"
 #include "app/sox/measure.h"
@@ -424,17 +425,25 @@ static u32 _bms_main_task_handler(void){
 
 extern void show_leds_for_charging(uint8_t charging);
 static debounce_t _charging_detect = {.count = 0, .max_count = 10, .init_count = 0};
+static int cs1180_may_error_count = 0;
 static void check_charging(){
 	/* 解决cs1180可能出错,导致误判充电,离仓后无法休眠 */
+	int may_error = 0;
 	if (measure_value()->load_current >= MIN_START_CHARGER_CURRENT) {
 		if (measure_value()->load_current != measure_value()->current_5238) {
 			if (measure_value()->current_5238 < 0.0f) { //cs1180检测到充电电流,5238检测到负电流
-				if (!io_state()->hall_detect) {
+				if (++cs1180_may_error_count >= 10) {
 					measure_value()->load_current = measure_value()->current_5238;
+					cs1180_adc_shutdown();
+					cs1180_may_error_count = 0;
 				}
+				may_error = 1;
 			}
 		}
 	}
+	if (may_error == 0) {
+		cs1180_may_error_count = 0;
+	}
 	if ((measure_value()->load_current >= MIN_START_CHARGER_CURRENT)) {
 		if (!_bms_state.charging) {
 			debounce_inc(_charging_detect);

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

@@ -14,7 +14,7 @@
 #define BATT_USED_BY_CHARGER_DOCKER 2
 #define HATT_USED_BY_CHARGER_BOX 3
 
-#define MIN_START_CHARGER_CURRENT 200 //ma, 如果有正向超过 MIN_START_CHARGER_CURRENT的电流,认为在充电
+#define MIN_START_CHARGER_CURRENT 300 //ma, 如果有正向超过 MIN_START_CHARGER_CURRENT的电流,认为在充电
 #define MIN_START_LOADING_CURRENT 5  //ma, 如果有反向小于 MIN_START_LOADING_CURRENT的电流,认为在放电
 #define MAX_DIFF_BETWEEN_MIN_MAX_CELL 150 //0.15v ,压差超过这个值,开始balance
 #define MIN_DIFF_BETWEEN_MIN_MAX_CELL 050 //0.05v, 牙差低于这个数据,停止balance

+ 12 - 1
Application/bsp/cs1180.c

@@ -3,6 +3,7 @@
 #include "cs1180.h"
 #include "clock.h"
 #include "libs/shark_types.h"
+#include "libs/shark_task.h"
 #include "libs/logger.h"
 /*
 注意:cs1 -> cs0 需要delay 一段时间,目前测试20us可以
@@ -270,6 +271,7 @@ int _cs1180_check_regs(int gain){
 }
 
 static int cs1180_reinit = 0;
+static u32 cs1180_reinit_time = 0;
 //return 1: cs1180 is OK, 0: cs1180 can not work
 int cs1180_adc_set_gain_online(int gain){
 	int count = 0;
@@ -281,11 +283,20 @@ int cs1180_adc_set_gain_online(int gain){
 		/*cs1180_adc_init();*/ //没有初始化成功过,或者校准没成功过
 		return _cs1180_ready;
 	}
+	if ((shark_get_seconds() - cs1180_reinit_time) < 10){
+		return _cs1180_ready;
+	}
+	cs1180_reinit_time = shark_get_seconds();
 	cs1180_reinit ++;
+
+	delay_us(50 * 1000);
+	CS1180_PWR_ENABLE(1);
+	delay_us(50 * 1000);
+	spi1_init();
+	delay_us(10);	
 	do {
 		cs1180_reset();
 		delay_us(10);
-		
 		cs1180_cs(0);
 		spi_write_reg(0x0, _cali_gain_regs + 16 * gain, 13);
 		cs1180_cs(1);

+ 2 - 0
Application/libs/shark_types.h

@@ -31,3 +31,5 @@ typedef enum { shark_false, shark_true } shark_bool;
 
 #define abs(x) (((x)>0)?(x):-(x))
 #define MAX(x, y) ((x)>(y)?(x):(y))
+#define MIN(x, y) ((x)<(y)?(x):(y))
+