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

1. update version tools
2. gd32 adc not over sample
3. cs1180 use 4 gains, 1X,8X,32X,128X
4. when open charger/discharger, need judge the temp first

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

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

+ 74 - 64
Application/app/sox/health.c

@@ -328,77 +328,87 @@ void health_process_aux_lock(void){
 
 
 void check_temp_state(void){
-	if (bms_state_get()->charging){
-		if (!_health.charger_over_temp){
-			if (_is_over_temp(charger_higher_high_temp)) {//超过允许的最高温度
-				debounce_inc(_charger_over_temp);
-			}else {
-				debounce_reset(_charger_over_temp);
-			}
-			if (debounce_reach_max(_charger_over_temp)){
-				_health.charger_over_temp = 1;
-				debounce_reset(_charger_over_temp);
-			}			
+	if (!_health.over_temp_deny_charger){
+		if (_is_over_temp(charger_higher_high_temp)) {//超过允许的最高温度
+			debounce_inc(_charger_over_temp);
+		}else {
+			debounce_reset(_charger_over_temp);
 		}
-		if (!_health.charger_lower_temp){
-			if (_is_low_temp(charger_lower_low_temp)) {//低于允许的最低温度
-				debounce_inc(_charger_lower_temp);
-			}else {
-				debounce_reset(_charger_lower_temp);
-			}
-			if (debounce_reach_max(_charger_lower_temp)) {
-				_health.charger_lower_temp = 1;
-				debounce_reset(_charger_lower_temp);
-			}
+		if (debounce_reach_max(_charger_over_temp)){
+			_health.over_temp_deny_charger = 1;
+			debounce_reset(_charger_over_temp);
+		}			
+	}
+	if (!_health.lower_temp_deny_charger){
+		if (_is_low_temp(charger_lower_low_temp)) {//低于允许的最低温度
+			debounce_inc(_charger_lower_temp);
+		}else {
+			debounce_reset(_charger_lower_temp);
 		}
-		if (_health.charger_over_temp || _health.charger_lower_temp) {
-			if (!_is_over_temp(charger_normal_high_temp) && !_is_low_temp(charger_normal_low_temp)){
-				debounce_inc(_charger_normal_temp);
-			}else {
-				debounce_reset(_charger_normal_temp);
-			}
-			if (debounce_reach_max(_charger_normal_temp)){
-				_health.charger_over_temp = 0;
-				_health.charger_lower_temp = 0;
-				debounce_reset(_charger_normal_temp);
-			}	
+		if (debounce_reach_max(_charger_lower_temp)) {
+			_health.lower_temp_deny_charger = 1;
+			debounce_reset(_charger_lower_temp);
 		}
-	}else {
-		if (!_health.discharger_over_temp){
-			if (_is_over_temp(discharger_higher_high_temp)) {//超过允许的最高温度
-				debounce_inc(_discharger_over_temp);
-			}else {
-				debounce_reset(_discharger_over_temp);
-			}
-			if (debounce_reach_max(_discharger_over_temp)){
-				_health.discharger_over_temp = 1;
-				debounce_reset(_discharger_over_temp);
-			}			
+	}
+	if (_health.lower_temp_deny_charger || _health.over_temp_deny_charger) {
+		if (!_is_over_temp(charger_normal_high_temp) && !_is_low_temp(charger_normal_low_temp)){
+			debounce_inc(_charger_normal_temp);
+		}else {
+			debounce_reset(_charger_normal_temp);
 		}
-		if (!_health.discharger_lower_temp){
-			if (_is_low_temp(discharger_lower_low_temp)) {//低于允许的最低温度
-				debounce_inc(_discharger_lower_temp);
-			}else {
-				debounce_reset(_discharger_lower_temp);
-			}
-			if (debounce_reach_max(_discharger_lower_temp)) {
-				_health.discharger_lower_temp = 1;
-				debounce_reset(_discharger_lower_temp);
-			}
+		if (debounce_reach_max(_charger_normal_temp)){
+			_health.over_temp_deny_charger = 0;
+			_health.lower_temp_deny_charger = 0;
+			debounce_reset(_charger_normal_temp);
+		}	
+	}
+
+	if (!_health.over_temp_deny_discharger){
+		if (_is_over_temp(discharger_higher_high_temp)) {//超过允许的最高温度
+			debounce_inc(_discharger_over_temp);
+		}else {
+			debounce_reset(_discharger_over_temp);
 		}
-		if (_health.discharger_over_temp || _health.discharger_lower_temp) {
-			if (!_is_over_temp(discharger_normal_high_temp) && !_is_low_temp(discharger_normal_low_temp)){
-				debounce_inc(_discharger_normal_temp);
-			}else {
-				debounce_reset(_discharger_normal_temp);
-			}
-			if (debounce_reach_max(_discharger_normal_temp)){
-				_health.charger_over_temp = 0;
-				_health.charger_lower_temp = 0;
-				debounce_reset(_discharger_normal_temp);
-			}	
+		if (debounce_reach_max(_discharger_over_temp)){
+			_health.over_temp_deny_discharger = 1;
+			debounce_reset(_discharger_over_temp);
+		}			
+	}
+	
+	if (!_health.lower_temp_deny_discharger){
+		if (_is_low_temp(discharger_lower_low_temp)) {//低于允许的最低温度
+			debounce_inc(_discharger_lower_temp);
+		}else {
+			debounce_reset(_discharger_lower_temp);
 		}
+		if (debounce_reach_max(_discharger_lower_temp)) {
+			_health.lower_temp_deny_discharger = 1;
+			debounce_reset(_discharger_lower_temp);
+		}
+	}
+	if (_health.lower_temp_deny_discharger || _health.over_temp_deny_discharger) {
+		if (!_is_over_temp(discharger_normal_high_temp) && !_is_low_temp(discharger_normal_low_temp)){
+			debounce_inc(_discharger_normal_temp);
+		}else {
+			debounce_reset(_discharger_normal_temp);
+		}
+		if (debounce_reach_max(_discharger_normal_temp)){
+			_health.over_temp_deny_discharger = 0;
+			_health.lower_temp_deny_discharger = 0;
+			debounce_reset(_discharger_normal_temp);
+		}	
+	}
+	if (bms_state_get()->charging){
+		_health.discharger_over_temp = 0;
+		_health.discharger_lower_temp = 0;		
+		_health.charger_over_temp = _health.over_temp_deny_charger;
+		_health.charger_lower_temp = _health.lower_temp_deny_charger;
 
+	}else {
+		_health.charger_over_temp = 0;
+		_health.charger_lower_temp = 0;
+		_health.discharger_over_temp = _health.over_temp_deny_discharger;
+		_health.discharger_lower_temp = _health.lower_temp_deny_discharger;
 	}
 	debug_health();
 }

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

@@ -34,6 +34,13 @@ typedef struct {
 	uint32_t discharger_cell_shutpower_voltage:1; //¹Ø±Õ¶¯Á¦
 	
 	uint32_t is_work_temp_lower:1;
+
+	uint32_t lower_temp_deny_charger:1;
+	uint32_t lower_temp_deny_discharger:1;
+	uint32_t over_temp_deny_charger:1;
+	uint32_t over_temp_deny_discharger:1;
+
+	
 	uint32_t res2:11;
 	uint8_t    internal_resistance[CELLS_NUM];   //cell's internal resistance
 }bms_health_t;

+ 18 - 12
Application/app/sox/measure.c

@@ -33,12 +33,12 @@ static float vim0_now;
 #define r_pcb_resistor 0.0f // pcb resistor
 static const float r_sense = r_resistor + r_pcb_resistor;
 static const float v_gd_ref = 3300.0f; //adc ref = 3.3v
-static const float max_gd_adc = 65535.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 max_cs1180_adc = 0x7FFFF;//
 static const float small_cur_r_sense = 360.0f;//ŷķ
 
-#define GD32_ADC_READ_TIMES 4
+#define GD32_ADC_READ_TIMES 128
 
 static void __inline__ select_gain_10x(int select){	
 	if (select){
@@ -56,6 +56,13 @@ static int __inline__ _is_x10_gain(void){
 	return imon_gain_now == imon_gain_10x;
 }
 
+float get_ml5238_gain(void){
+	return imon_gain_now;
+}
+
+float get_ml5238_vos(void){
+	return vim0_now;
+}
 static void current_10x_calibrate(void){
 	/* calibrate the 10x gain */
 	ML5238_IMON_OUT_ZERO_10X();
@@ -73,20 +80,20 @@ static void current_50x_calibrate(void){
 	vim0_50x = adc_sample_avg(ADC_CHAN_IMON, GD32_ADC_READ_TIMES);
 	ML5238_IMON_OUT_V2000_50X();
 	float vim1 = adc_sample_avg(ADC_CHAN_IMON, GD32_ADC_READ_TIMES);
-	ML5238_IMON_OUT_V100_50X();
+	ML5238_IMON_OUT_V20_50X();
 	float vr = adc_sample_avg(ADC_CHAN_IMON, GD32_ADC_READ_TIMES);
-	imon_gain_50x = ML5238_GAIN(vim0_50x, vim1, vr);
+	imon_gain_50x = 50.0f;//ML5238_GAIN(vim0_50x, vim1, vr);
 }
 
 /*calibrate when startup && temperature is changed more than 5? degree
 * calibrate the ms5238's IMON output voltage gain
 */
 void current_calibrate(void){
-#ifdef gain_default_50x
+	current_10x_calibrate();
 	current_50x_calibrate();
+#ifdef gain_default_50x
 	select_gain_10x(0);
 #else
-	current_10x_calibrate();
 	select_gain_10x(1);
 #endif
 }
@@ -103,15 +110,14 @@ void measure_adc_init(void){
 /* 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);
-	if (adc >= 0xFFF0 && (!_is_x10_gain())){//overflow, use 10x gain
-		current_10x_calibrate();
+	if (adc >= (max_gd_adc - 0xF) && (!_is_x10_gain())){//overflow, use 10x gain
 		select_gain_10x(1);
 		adc = adc_sample_avg(ADC_CHAN_IMON, GD32_ADC_READ_TIMES);
 	}else if (adc <= 0x1F && (_is_x10_gain())){// is too small, select 50x gain
-		current_50x_calibrate();
 		select_gain_10x(0); 
 		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);
@@ -126,7 +132,7 @@ static float get_pack_current_by_cs1180(void){
 
 float get_pack_current(void){
 	float current = get_pack_current_by_gd();
-	if (abs(current) < CS1180_MAX_CURRENT && cs1180_is_ready()){
+	if (cs1180_change_gain(current) == 0) {
 		current = get_pack_current_by_cs1180();
 	}
 	return current;
@@ -159,7 +165,7 @@ float get_small_current_voltage(void){
 int get_pcb_temperature(void){
 	TEMP_OPEN(1);
 	delay_us(100);
-	uint16_t adc = adc_sample(ADC_CHAN_TEMPERATURE_4, TRUE);
+	uint16_t adc = adc_sample_avg(ADC_CHAN_TEMPERATURE_4, 1);
 	TEMP_OPEN(0);
 	return get_temp_by_adc(adc);
 }
@@ -170,7 +176,7 @@ int get_pcb_temperature(void){
 int get_pack_temperature(int index){
 	TEMP_OPEN(1);
 	delay_us(100);
-	uint16_t adc = adc_sample(ADC_CHAN_TEMPERATURE_1 + index, TRUE);
+	uint16_t adc = adc_sample_avg(ADC_CHAN_TEMPERATURE_1 + index, 1);
 	TEMP_OPEN(0);
 	return get_temp_by_adc(adc);
 }

+ 2 - 0
Application/app/sox/measure.h

@@ -8,6 +8,8 @@ float get_small_current_voltage(void);
 int get_pcb_temperature(void);
 int get_pack_temperature(int index);
 void current_calibrate(void);
+float get_ml5238_gain(void);
+float get_ml5238_vos(void);
 
 #endif /* _IV_Measure_H__ */
 

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

@@ -40,6 +40,7 @@ void measure_log(void){
 	for (int i = 0; i < CELLS_NUM; i++){
 		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());
 }
 /*
  * 测量电芯电压,计算出总电压, 测量总电流,放电和充电

+ 3 - 3
Application/app/sox/soc.c

@@ -149,8 +149,8 @@ void soc_update(void){
 		_soc.total_coulomb += _soc.pre_discharger_coulomb / 3600.0f;
 		chargering = 0;
 	}
-	float current = measure_value()->load_current / 1000.0f; //A
-	float delta_q = current * _delta_time();
+	double current = measure_value()->load_current / 1000.0f; //A
+	double delta_q = current * _delta_time();
 	if (chargering){
 		delta_q = delta_q * _charger_coefficient;
 		_soc.charger_coulomb += abs(delta_q);
@@ -158,7 +158,7 @@ void soc_update(void){
 		delta_q = delta_q * _discharger_coefficient;
 		_soc.dischrger_coulomb += abs(delta_q); //转为正数
 	}
-	_soc.coulomb_now += delta_q; //充电加, 放电减
+	_soc.coulomb_now = _soc.coulomb_now + delta_q; //充电加, 放电减
 
 	if (_soc.coulomb_now > _soc.coulomb_max){
 		_soc.coulomb_now = _soc.coulomb_max;

+ 9 - 9
Application/app/sox/soc.h

@@ -6,17 +6,17 @@
 #define SOC_FLAG_CALIBRATED 1 //已经校准
 typedef struct {
 	uint8_t flags; //比如是否校准等
-	float coulomb_now; /*AH, 若导线中载有1安培的稳定电流,则在1秒内通过导线横截面积的电量为1库仑 */
+	double coulomb_now; /*AH, 若导线中载有1安培的稳定电流,则在1秒内通过导线横截面积的电量为1库仑 */
 	uint8_t capacity;  /* 电池的容量百分比 */
-	float coulomb_min;
-	float coulomb_max;
-	float power; //功率,当前的电压 x 当前的电流(w)
-	float energy; //当前的能量(wh)
-	float charger_coulomb; //本次充电的AH
-	float dischrger_coulomb; //本次放电的AH
+	double coulomb_min;
+	double coulomb_max;
+	double power; //功率,当前的电压 x 当前的电流(w)
+	double energy; //当前的能量(wh)
+	double charger_coulomb; //本次充电的AH
+	double dischrger_coulomb; //本次放电的AH
 
-	float pre_charger_coulomb;
-	float pre_discharger_coulomb;
+	double pre_charger_coulomb;
+	double pre_discharger_coulomb;
 
 	uint32_t total_coulomb;
 }soc_t;

+ 6 - 4
Application/app/sox/state.c

@@ -146,13 +146,15 @@ static s32 _process_unheath(void){
 		unhealth = (Health_Discharger_Failt | Health_charger_Fault);
 	}
 
-	if (bms_health()->charger_over_current || bms_health()->charger_over_temp || bms_health()->charger_lower_temp){
+	if (bms_health()->charger_over_current || bms_health()->charger_over_temp || bms_health()->charger_lower_temp ||
+				bms_health()->over_temp_deny_charger|| bms_health()->lower_temp_deny_charger){
 		charger_open(0); //disable charger mosfet
 		_bms_state.charging = 0;
 		unhealth |= Health_charger_Fault;
 	}
 
-	if (bms_health()->discharger_over_temp || bms_health()->discharger_lower_temp || bms_health()->discharger_lower_voltage){
+	if (bms_health()->discharger_over_temp || bms_health()->discharger_lower_temp || bms_health()->discharger_lower_voltage ||
+				bms_health()->over_temp_deny_discharger|| bms_health()->lower_temp_deny_discharger){
 		discharger_open(0); //disable charger mosfet
 		unhealth |= Health_Discharger_Failt;
 		if (bms_health()->discharger_over_temp){ //放电过高温后,小电流也必须关闭
@@ -165,7 +167,7 @@ static s32 _process_unheath(void){
 		unhealth |= Health_aux_Fault;
 	}
 	
-	return Health_Success;
+	return unhealth;
 }
 
 
@@ -314,7 +316,7 @@ static void check_charging(){
 			_bms_state.charging = 1;
 			debounce_reset(_charging_detect);
 		}
-	}else if ((measure_value()->load_current < MIN_START_CHARGER_CURRENT) && _bms_state.charging){
+	}else if ((measure_value()->load_current < MIN_START_LOADING_CURRENT) && _bms_state.charging){
 		debounce_dec(_charging_detect);
 		if (debounce_reach_zero(_charging_detect)){
 			_bms_state.charging = 0;

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

@@ -14,8 +14,8 @@
 #define BATT_USED_BY_CHARGER_DOCKER 2
 #define HATT_USED_BY_CHARGER_BOX 3
 
-#define MIN_START_CHARGER_CURRENT 5 //ma, 如果有正向超过 MIN_START_CHARGER_CURRENT的电流,认为在充电
-//#define MIN_START_LOADING_CURRENT 2  //ma, 如果有反向小于 MIN_START_LOADING_CURRENT的电流,认为在放电
+#define MIN_START_CHARGER_CURRENT 50 //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
 #define CELL_FUSION_VOLTAGE      3500 //LFP电池在3.5v的时候,开始发散,需要判断是否要balance

+ 0 - 2
Application/bsp/bsp.c

@@ -17,8 +17,6 @@ const char iap_board_name[] __attribute__((at(0x08002800))) = "SP600";
 const char iap_fw_version[] __attribute__((at(0x08002A00))) = CONFIG_VERSION;
 const char iap_fw_name[] __attribute__((at(0x08002C00))) = "App";
 
-#define CONFIG_DEBUG 0
-
 extern void system_clock_config(void);
 extern void SystemCoreClockUpdate(void);
 #define ALARM_TEST 1

+ 74 - 9
Application/bsp/cs1180.c

@@ -2,6 +2,8 @@
 #include "spi.h"
 #include "cs1180.h"
 #include "clock.h"
+#include "libs/shark_types.h"
+#include "libs/logger.h"
 
 #define CS1180_RDATA    0X01
 #define CS1180_RDATAC   0X03
@@ -19,7 +21,9 @@
 #define CS1180_RESET    0xfe
 
 static float _cs1180_gain = 1.0f;
-#define CS1180_INIT_GAIN CS1180_GAIN_128X
+static int CS1180_NOW_GAIN = CS1180_GAIN_128X;
+
+static uint8_t _cali_gain_regs[16 * 8];
 
 static int cs1180_send_cmd(uint8_t data);
 static uint8_t cs1180_read_data(uint8_t data);
@@ -55,8 +59,8 @@ static void spi_read_reg(uint8_t reg, uint8_t *data, uint8_t len){
 	}
 }
 
-static uint8_t cs1180_dumy_read(void){
-	uint8_t data[16] = {0x5A, 0x5A, 0x5A};
+static uint8_t cs1180_dumy_read(int gain){
+	uint8_t *data = _cali_gain_regs + 16 * gain;
 	while (IS_CS1180_NOT_READY());
 	cs1180_cs(0);
 	cs_delay();
@@ -148,10 +152,10 @@ static void _cs1180_adc_set_gain(int gain){
 	cs1180_cs(1);
 	_cs1180_gain = 1 << gain;
 	cs1180_self_calibrate();
-	cs1180_dumy_read();	
+	cs1180_dumy_read(gain);	
 }
 
-int cs1180_adc_set_gain(int gain){
+int cs1180_adc_set_gain_cali(int gain){
 	int count = 0;
 	do {
 		cs1180_reset();
@@ -160,19 +164,19 @@ int cs1180_adc_set_gain(int gain){
 		_cs1180_adc_set_gain(gain);
 		delay_us(10);
 
-		if (cs1180_dumy_read() == gain){
+		if (cs1180_dumy_read(gain) == gain){
 			break;
 		}
 		count ++;
 	}while(count <= 20);
 	if (count >= 20) {
-		if (cs1180_dumy_read() != gain){
+		if (cs1180_dumy_read(gain) != gain){
 			return -1;
 		}
 	}
 	delay_us(10*1000);
 	cs1180_sys_offset_calibrate();
-	cs1180_dumy_read();
+	cs1180_dumy_read(gain);
 	return 0;
 }
 
@@ -193,10 +197,71 @@ void cs1180_adc_init(void){
 	delay_us(200 * 1000);
 	spi1_init();
 	delay_us(10);
-	_cs1180_ready = cs1180_adc_set_gain(CS1180_INIT_GAIN) == 0;
+	cs1180_adc_set_gain_cali(CS1180_GAIN_1X);
+	cs1180_adc_set_gain_cali(CS1180_GAIN_8X);
+	cs1180_adc_set_gain_cali(CS1180_GAIN_32X);
+	cs1180_adc_set_gain_cali(CS1180_GAIN_128X);
+	_cs1180_ready = _cali_gain_regs[16 * CS1180_NOW_GAIN] == CS1180_NOW_GAIN;
+}
+
+int _cs1180_read_gain(void){
+	uint8_t data[] = {0xff, 0xff, 0xff};
+	cs1180_cs(0);
+	cs_delay();	
+	spi_read_reg(0x0, data, 3);
+	cs1180_cs(1);
+	
+	return data[0];
+}
+
+int cs1180_adc_set_gain_online(int gain){
+	int count = 0;
+	if (_cali_gain_regs[16 * CS1180_NOW_GAIN] == gain){
+		return 0;
+	}
+	sys_debug("change gain to %d\n", gain);
+	do {
+		cs1180_reset();
+		delay_us(10);
+
+		cs1180_cs(0);
+		cs_delay();
+		spi_write_reg(0x0, _cali_gain_regs + 16 * gain, 16);
+		cs1180_cs(1);
+		delay_us(10);
+
+		if (_cs1180_read_gain() == gain){
+			break;
+		}
+		count ++;
+	}while(count <= 5);
+	if (count >= 5) {
+		if (_cs1180_read_gain() != gain){
+			sys_error("change gain error!!!\n");
+			return -1;
+		}
+	}
+	CS1180_NOW_GAIN = gain;
+	_cs1180_gain = 1 << gain;
+	sys_debug("change gain success!\n");
+	return 0;
+
 }
 
 
+int cs1180_change_gain(int current){
+	if (abs(current) < 3000){ //4.5
+		return cs1180_adc_set_gain_online(CS1180_GAIN_128X);
+	}else if (abs(current) < 12 * 1000){ //18
+		return cs1180_adc_set_gain_online(CS1180_GAIN_32X);
+	}else if (abs(current) < 48 * 1000){ //72
+		return cs1180_adc_set_gain_online(CS1180_GAIN_8X);
+	}/*else if (abs(current) < 160 * 1000){
+		return cs1180_adc_set_gain_online(CS1180_GAIN_1X);
+	}*/
+	return -1;
+}
+
 void cs1180_adc_shutdown(void){
 	CS1180_PWR_ENABLE(0);
 	spi1_deinit();

+ 1 - 0
Application/bsp/cs1180.h

@@ -16,6 +16,7 @@ int cs1180_is_ready(void);
 int cs1180_adc_set_gain(int gain);
 void cs1180_sys_offset_calibrate(void);
 float cs1180_adc_sample(void);
+int cs1180_change_gain(int current);
 
 #endif /* _CS1180_H__ */
 

+ 5 - 4
Application/bsp/gd32_adc.c

@@ -19,7 +19,7 @@ void gd32_adc_init(void){
 	gpio_mode_analog_input(GPIOB, GPIO_PIN_1|GPIO_PIN_0);
 
     /* config ADC clock */
-    rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6); //adc clock:7M 
+    rcu_adc_clock_config(RCU_ADCCK_APB2_DIV8); //adc clock:7M 
 
 	rcu_periph_clock_enable(RCU_ADC);
 	adc_deinit();
@@ -211,9 +211,10 @@ int adc_sample_avg(int chan, int times){
 	int count = 0;
 	int min = 0xFFFFF;
 	int max = -0xFFFFF;
+	//gd32_adc_init();
 	//hardware oversample to 16bit
-	adc_oversample_mode_config(ADC_OVERSAMPLING_ALL_CONVERT, ADC_OVERSAMPLING_SHIFT_2B, ADC_OVERSAMPLING_RATIO_MUL64);
-	adc_oversample_mode_enable();
+	//adc_oversample_mode_config(ADC_OVERSAMPLING_ALL_CONVERT, ADC_OVERSAMPLING_SHIFT_2B, ADC_OVERSAMPLING_RATIO_MUL64);
+	//adc_oversample_mode_enable();
     /* use max convert time to make sure the adc work fine */
     adc_regular_channel_config(0, chan, ADC_SAMPLETIME_55POINT5);////55.5 + 12.5 = 68 cycle, 68 * 256/(7*1000000)
 	adc_enable();
@@ -226,7 +227,7 @@ int adc_sample_avg(int chan, int times){
     	while(SET != adc_flag_get(ADC_FLAG_EOC));
     	int one = adc_regular_data_read();
 		adc_flag_clear(ADC_FLAG_EOC);		
-		value += (one & 0xFFFF);
+		value += (one & 0xFFF);
 		count ++;
 		if (one > max){
 			max = one;

+ 1 - 1
Application/bsp/ml5238.h

@@ -57,7 +57,7 @@ int ml5238_write(uint8_t regaddr, uint8_t data);
 
 /* IMON output 100mV, used to cali the GAIN */
 #define ML5238_IMON_OUT_V100_10X() {ml5238_write(ML5238_IMON, 0x1c);delay_us(1000);};
-#define ML5238_IMON_OUT_V100_50X() {ml5238_write(ML5238_IMON, 0x1d);delay_us(5000);};
+#define ML5238_IMON_OUT_V20_50X() {ml5238_write(ML5238_IMON, 0x1d);delay_us(5000);};
 
 /* IMON output real pin's voltage */
 #define ML5238_IMON_OUT_10X() {ml5238_write(ML5238_IMON, 0x10);delay_us(1000);};