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

增加adc的矫正功能

Signed-off-by: huhui <huhui@sharkgulf.com>
huhui 5 лет назад
Родитель
Сommit
63c734c291

+ 16 - 2
Application/app/bms_message.c

@@ -32,6 +32,7 @@ void process_bms_message(can_frame_t *frame, int len){
 	int result = 0;
 	uint8_t *data = NULL;
 	int data_len = 0;
+	set_log_all(L_debug);
 	switch(frame->key) {
 		case CAN_KEY_BMS_SET_POWER:
 			if (len != sizeof(pwr_cmd_t)){
@@ -205,8 +206,21 @@ void process_bms_message(can_frame_t *frame, int len){
 			protocol_send_ack(frame->head.can_addr, frame->key, result);
 			break;
 		case CAN_KEY_START_CALI:
-			//measure_start_cali();
-			protocol_send_ack(frame->head.can_addr, frame->key, 1);
+			if (len != sizeof(cali_cmd_t)) {
+				result = 0;
+			}else {
+				cali_cmd_t * cmd = (cali_cmd_t *)frame->data;
+				uint8_t adc = cmd->flags & 0x01;
+				uint8_t flags = ((cmd->flags>>1) & 0x03);
+				if (flags == 1) {
+					result = measure_start_cali(adc, cmd->gain, cmd->totol_samples);
+				}else if (flags == 2) {
+					result = measure_continue_cali(adc, cmd->voltage, cmd->current);
+				}else {
+					result = measure_stop_cali(adc, cmd->gain);
+				}
+			}
+			protocol_send_ack(frame->head.can_addr, frame->key, result);
 			break;
 	}
 }

+ 9 - 0
Application/app/protocol.h

@@ -128,6 +128,15 @@ typedef struct {
 #define CAN_KEY_GET_SN      0x05 //return string
 
 #define CAN_KEY_START_CALI  0xa8
+#pragma  pack (push,1)
+typedef struct {
+	uint8_t  flags; // bit0:1-cs1180, 0- ml5238, bit1-2 0:stop, 1:start, 2: continue
+	uint8_t  gain;
+	uint8_t  totol_samples;
+	int16_t current;
+	uint16_t voltage;
+}cali_cmd_t;
+#pragma pack(pop)
 
 #define CAN_KEY_PCBA_TEST 0xa9
 

+ 1 - 1
Application/app/protocol_old.c

@@ -146,7 +146,7 @@ static int protocol_old_process_binary(uart_enum_t uart_no, uint8_t *data, int l
 	if (response_len <= 0){
 		return -1;
 	}
-	log_disable_all();
+	set_log_all(L_disable);
 	shark_uart_write_bytes(current_uart, response_data, response_len);
 	return 0;
 

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

@@ -11,6 +11,7 @@ void least_square_init(least_square_t *ls, int samples){
 	ls->mul_xy = 0;
 	ls->sum_x = 0;
 	ls->sum_y = 0;
+	ls->finished = 0;
 }
 int least_square_put(least_square_t *ls, double x, double y){
 	if (ls->num_samples < ls->max_samples){
@@ -36,6 +37,7 @@ int least_square_put(least_square_t *ls, double x, double y){
 		ls->sum_y -= ls->last_y;
 		ls->last_x = x;
 		ls->last_y = y;
+		ls->finished = 1;
 		return 1;
 	}
 }

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

@@ -11,6 +11,7 @@ typedef struct {
 	double sum_y;
 	double Ka;
 	double Cb;
+	int finished;
 }least_square_t;
 
 void least_square_init(least_square_t *ls, int samples);

+ 81 - 1
Application/app/sox/measure.c

@@ -7,6 +7,9 @@
 #include "bsp/temp_lookup_tab.h"
 #include "bsp/shark_bsp.h"
 #include "libs/logger.h"
+#include "Least_Square.h"
+#include "app/sox/state.h"
+
 /* measure the temp & current & voltage for battery pack by using
  * ms5238 & cs1180(only used when bms is in small current loading)
 */
@@ -27,6 +30,17 @@ static float imon_gain_now;
 static float vim0_10x = 0.0f;
 static float vim0_50x = 0.0f;
 static float vim0_now;
+static float ml5238_10x_a = 1.0f;
+static float ml5238_50x_a = 1.0f;
+
+static float ml5238_10x_b = 0.0f;
+static float ml5238_50x_b = 0.0f;
+
+static float ml5238_now_a = 1.0f;
+static float ml5238_now_b = 0.0f;
+
+static float cs1180_a = 1.0f;
+static float cs1180_b = 0.0f;
 
 #define gain_default_50x 1
 #define CS1180_MAX_CURRENT 4500 //MA, cs1180的最大电流,超过这个使用ML5238
@@ -37,6 +51,7 @@ 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 max_cs1180_adc = 0x7FFFF;//
 static const float small_cur_r_sense = 360.0f;//欧姆
+static least_square_t adc_cali[2]; // y = ax + b
 
 #define GD32_ADC_READ_TIMES 128
 
@@ -45,10 +60,14 @@ static void __inline__ select_gain_10x(int select){
 		ML5238_IMON_OUT_10X();
 		imon_gain_now = imon_gain_10x;
 		vim0_now = vim0_10x;
+		ml5238_now_a = ml5238_10x_a;
+		ml5238_now_b = ml5238_10x_b;
 	}else {
 		ML5238_IMON_OUT_50X();
 		imon_gain_now = imon_gain_50x;
 		vim0_now = vim0_50x;
+		ml5238_now_a = ml5238_50x_a;
+		ml5238_now_b = ml5238_50x_b;
 	}
 }
 
@@ -115,6 +134,13 @@ void measure_adc_init(void){
 	set_log_level(MOD_SYSTEM, L_debug);
 }
 
+static float get_current_by_ml5238(void){
+	float adc = adc_sample_avg(ADC_CHAN_IMON, GD32_ADC_READ_TIMES);
+	float cali_adc = ML5238_V_RSENSER(adc, vim0_now, imon_gain_now);
+
+	return (int)((cali_adc / max_gd_adc) * v_gd_ref / r_sense * 1000);
+}
+
 /* get battery pack's current (mA) */
 static float get_pack_current_by_gd(void){
 	float adc = adc_sample_avg(ADC_CHAN_IMON, GD32_ADC_READ_TIMES);
@@ -139,6 +165,7 @@ static float get_pack_current_by_cs1180(int *valid){
 
 float get_pack_current(int *current_5238){
 	float current = get_pack_current_by_gd();
+	current = ml5238_now_a * current + ml5238_now_b;
 	if (current_5238 != NULL){
 		*current_5238 = (int)current;
 	}
@@ -146,7 +173,7 @@ float get_pack_current(int *current_5238){
 		int valid = 1;
 		float cs1180_current = get_pack_current_by_cs1180(&valid);
 		if (valid == 1) {
-			current = cs1180_current;
+			current = cs1180_current * cs1180_a + cs1180_b;
 		}
 	}
 	return current;
@@ -195,3 +222,56 @@ int get_pack_temperature(int index){
 	return get_temp_by_adc((adc<<4)&0xFFFF);
 }
 
+int measure_start_cali(uint8_t adc, uint8_t gain, uint8_t samples){
+	bms_work_mode_set(WORK_MODE_CALIBRATE, 1);
+	least_square_init(&adc_cali[adc], samples);
+	sys_debug("start cali %d, %d, %d\n", adc, gain, samples);
+	if (adc == GD32_ADC) {
+		if (gain == 10) {
+			select_gain_10x(1);
+		}else if (gain == 50) {
+			select_gain_10x(0);
+		}else {
+			return 0;
+		}
+		return 1;
+	}
+	return 1;
+}
+
+int measure_continue_cali(uint8_t adc, uint16_t voltage, int16_t current) {
+	float x = 0;
+	float y = current;
+	sys_debug("continue cali %d, %d, %d\n", adc, voltage, current);
+	if (adc == GD32_ADC) {
+		x = get_current_by_ml5238();
+	}else {
+		x = get_pack_current_by_cs1180(NULL);
+	}
+	least_square_put(&adc_cali[adc], x, y);
+	return 1;
+}
+
+int measure_stop_cali(uint8_t adc, uint8_t gain){
+	bms_work_mode_set(WORK_MODE_CALIBRATE, 0);
+	sys_debug("continue stop %d, %d\n", adc, gain);
+	if (adc_cali[adc].finished ) {
+		if (adc == GD32_ADC) {
+			if (gain == 10) {
+				ml5238_10x_a = adc_cali[adc].Cb;
+				ml5238_10x_b = adc_cali[adc].Ka;
+			}else if (gain == 50) {
+				ml5238_50x_a = adc_cali[adc].Cb;
+				ml5238_50x_b = adc_cali[adc].Ka;
+			}
+		}else {
+			cs1180_a = adc_cali[adc].Cb;
+			cs1180_b = adc_cali[adc].Ka;
+		}
+		sys_debug("stop %f, %f\n", adc_cali[adc].Cb, adc_cali[adc].Ka);
+	}
+	select_gain_10x(0);
+	return adc_cali[adc].finished;
+}
+
+

+ 7 - 1
Application/app/sox/measure.h

@@ -1,5 +1,8 @@
 #ifndef _IV_Measure_H__
 #define _IV_Measure_H__
+
+#include <stdint.h>
+
 void measure_adc_init(void);
 float get_pack_current(int *current_5238);
 float get_cell_voltage(int cell);
@@ -10,7 +13,10 @@ int get_pack_temperature(int index);
 void current_calibrate(void);
 float get_ml5238_gain(void);
 float get_ml5238_vos(void);
-void measure_start_cali(void);
+int measure_start_cali(uint8_t adc, uint8_t gain, uint8_t samples);
+int measure_continue_cali(uint8_t adc, uint16_t voltage, int16_t current);
+int measure_stop_cali(uint8_t adc, uint8_t gain);
+
 
 #endif /* _IV_Measure_H__ */
 

+ 6 - 1
Application/app/sox/measure_task.c

@@ -41,6 +41,8 @@ void measure_log(void){
 		//measure_debug("Cell[%d]: %.3fv\n", i, _measure_value.cell_vol[i]/1000.0f);
 	}
 	measure_debug("Gain:%f, Off %f\n", get_ml5238_gain(), get_ml5238_vos());
+
+	cs1180_log();
 }
 /*
  * 测量电芯电压,计算出总电压, 测量总电流,放电和充电
@@ -59,6 +61,9 @@ static void init_current_voltage_task(void){
 }
 
 static u32 current_voltage_task_handler(void){
+	if (bms_work_is_calibrating()){
+		return _current_voltage_task.delay;
+	}
 	/* 测量电流 */
 	_measure_value.load_current = get_pack_current(&_measure_value.current_5238);
 	_current_notify();//通知bms state 有新的电流数据
@@ -88,7 +93,7 @@ static void init_temp_task(void){
 	shark_task_add(&_temp_task._task);
 }
 static u32 temp_task_handler(void){
-	_measure_value.pack_temp[_temp_task.index] = get_pack_temperature(_temp_task.index);
+	_measure_value.pack_temp[_temp_task.index] = 25;//get_pack_temperature(_temp_task.index);
 	_temp_task.index = (_temp_task.index + 1) % (PACK_TEMPS_NUM);
 	_temperature_notify();//通知bms state 有新的温度数据
 	return _temp_task.delay;

+ 2 - 2
Application/bsp/shark_bsp.h

@@ -28,8 +28,8 @@
 #define CELLS_NUM 15
 #define PACK_TEMPS_NUM 4
 #define PCB_TEMP_INDEX 3
-#define GD32_ADC (1<<0)
-#define CS1180_ADC (1<<1)
+#define GD32_ADC 0
+#define CS1180_ADC 1
 
 #define UART_TIMEOUT 3000
 #define CHARGER_DETECT_IRQ_CLEAR_TIMEOUT (UART_TIMEOUT + 2 * 1000)

+ 1 - 1
Application/bsp/spi.c

@@ -57,7 +57,7 @@ void spi1_init(void){
     spi_init_struct.frame_size           = SPI_FRAMESIZE_8BIT;
     spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
     spi_init_struct.nss                  = SPI_NSS_SOFT;
-    spi_init_struct.prescale             = SPI_PSC_128 ;
+    spi_init_struct.prescale             = SPI_PSC_256 ;
     spi_init_struct.endian               = SPI_ENDIAN_MSB;
     spi_init(SPI1, &spi_init_struct);
 

+ 4 - 3
Application/libs/logger.c

@@ -18,9 +18,10 @@ void set_log_level(int mod, int l){
 	level_data[index] = (level_data[index] & (~(LEVEL_MASK<<mod))) | ((l & LEVEL_MASK)<<mod);
 }
 
-void log_disable_all(void){
-	level_data[0] = 0;
-	level_data[1] = 0;
+void set_log_all(int l){
+	for (int i = 0; i < 32; i++){
+		set_log_level(i, l);
+	}
 }
 
 static void log_out(char *fmt, va_list args){

+ 1 - 1
Application/libs/logger.h

@@ -25,7 +25,7 @@ extern void set_log_level(int mod, int l);
 extern void log_debug(int mod, char *fmt, ...);
 extern void log_warning(int mod, char *fmt, ...);
 extern void log_error(int mod, char *fmt, ...);
-extern void log_disable_all(void);
+extern void set_log_all(int l);
 /* logger functions */
 #define io_debug(fmt, args...) log_debug(MOD_IO, "D"fmt, ##args)
 #define io_warning(fmt, args...) log_warning(MOD_IO, "W"fmt, ##args)