#include "kit_data.h" #include "kit_debug.h" #include "bsp_task.h" #include "iso_check.h" #include "soc_calculate.h" #include "adc_manager.h" #include "gpio_manager.h" #include "eeprom_manager.h" #include "hv_adc_manager.h" #include "table_comm.h" //#include "drv_mcp3208.h" #include "drv_ads8688.h" #define CUR_FILTER_ENABLE (0u) #define ADCIC_SAMPLE_CNT (4u) ADS8688_STATIC_INIT(ads8688, kSpiDev_2, kGpioType_ADC_Cs); typedef enum { kAdIc_Hv1, kAdIc_HvBat, kAdIc_Cur, kAdIc_HvIso, kAdIc_HvIsoNagtive, kAdIc_End } AdIcEnum; typedef struct { bool is_simulate; uint8_t filter_pos; uint8_t ad_buf_pos[kAdIc_End]; int16_t current; uint16_t en_temp[kEnTemp_End]; int32_t can_current; int16_t show_current; #if CUR_FILTER_ENABLE int16_t filter_current[MCP3208_SAMPLE_CNT]; #endif int32_t value[kAdIc_End]; int32_t ad_avg[kAdIc_End]; int32_t ad_buf[kAdIc_End][ADCIC_SAMPLE_CNT]; } CurHvItem; CurHvItem cur_hv_item; typedef enum { kCurSensor_Shunt, kCurSensor_SigHall, kCurSensor_DualHall, kCurSensor_SigHall_Base, kCurSensor_End, } CurSensorType; typedef struct { int8_t dir; CurSensorType type; int16_t filter; int16_t offset; int32_t scale; } CurProp; typedef struct { uint8_t shunt_volt; int8_t chg_cur_dir; CurChannel channel; int16_t swing_volt; CurProp prop[kCurChannel_End]; } CurItem; CurItem cur_item; void bms_init_current(void) { cur_item.swing_volt = get_eeprom_data(kEep_HallSwingVolt, kEepromDataType_Full); cur_item.shunt_volt = get_eeprom_data(kEep_ChgCurDir_ShuntRatedVolt, kEepromDataType_Low); cur_item.prop[0].filter = cur_item.prop[1].filter = 0; // 上位机下发时缩小10倍 cur_item.prop[0].scale = get_eeprom_data(kEep_CurSensor2_1Range, kEepromDataType_Low) * 10; cur_item.prop[1].scale = get_eeprom_data(kEep_CurSensor2_1Range, kEepromDataType_High) * 10; cur_item.prop[0].type = (CurSensorType)get_eeprom_data(kEep_CurSensor2_1Type, kEepromDataType_Low); cur_item.prop[1].type = (CurSensorType)get_eeprom_data(kEep_CurSensor2_1Type, kEepromDataType_High); cur_item.prop[0].offset = cur_item.prop[1].offset = 0; // 电流方向 cur_item.chg_cur_dir = 1 - (int8_t)((get_eeprom_data(kEep_ChgCurDir_ShuntRatedVolt, kEepromDataType_High) & 0x01) << 1); cur_item.prop[0].dir = 1 - (int8_t)((get_eeprom_data(kEep_CurSensor2_1Dir, kEepromDataType_High) & 0x01) << 1); cur_item.prop[1].dir = 1 - (int8_t)((get_eeprom_data(kEep_CurSensor2_1Dir, kEepromDataType_Low) & 0x01) << 1); } void bms_adjust_cur(void) { uint32_t i; int32_t cur, max_cur = INT32_MIN, min_cur = INT32_MAX; for (i = 0; i < 20; i++) { bms_poll_adc(10); cur = bms_poll_cur_hv(0); if (cur > max_cur) { max_cur = cur; } if (cur < min_cur) { min_cur = cur; } kit_time_dly_ms(5); } cur = 0; if ((min_cur > -500) && (max_cur < 500)) { // 计算滤波 + 0.1A cur = ((max_cur - min_cur) >> 1) + 10; } // 电流滤波单位 0.1A/bit 计算电流0.01A/bit 需要*10 cur_item.prop[0].filter = get_eeprom_data(kEep_ZeroFilter2_1Filter, kEepromDataType_Low) * 10; cur_item.prop[1].filter = get_eeprom_data(kEep_ZeroFilter2_1Filter, kEepromDataType_High) * 10; if (cur_item.prop[0].filter == 0) { cur_item.prop[0].filter = cur; } if (cur_item.prop[1].filter == 0) { cur_item.prop[1].filter = cur; } bsp_eeprom_set_data(kEep_ZeroFilter2_1Filter, cur / 10, kEepromDataType_Low); bsp_eeprom_set_data(kEep_ZeroFilter2_1Filter, cur / 10, kEepromDataType_High); cur = 0; if ((min_cur > -500) && (max_cur < 500)) { // 计算偏移 cur = ((max_cur + min_cur) >> 1); } // 电流偏移单位 0.1A/bit,偏移12A 计算电流0.01A/bit 需要*10 cur_item.prop[0].offset = ((int8_t)get_eeprom_data(kEep_CurSensor2_1Offset, kEepromDataType_Low)) * 10; cur_item.prop[1].offset = ((int8_t)get_eeprom_data(kEep_CurSensor2_1Offset, kEepromDataType_High)) * 10; if (cur_item.prop[0].offset == 0) { cur_item.prop[0].offset = cur; } if (cur_item.prop[1].offset == 0) { cur_item.prop[1].offset = cur; } bsp_eeprom_set_data(kEep_CurSensor2_1Offset, cur / 10, kEepromDataType_Low); bsp_eeprom_set_data(kEep_CurSensor2_1Offset, cur / 10, kEepromDataType_High); // 根据校准值再计算下电流 bms_poll_adc(10); bms_poll_cur_hv(10); } // 分流器转换 uint32_t HighResCurTrans(int32_t voldata) { uint16_t Rsense = 39; uint32_t highResCurdata = 0; highResCurdata = voldata * Rsense * 100;//扩大100倍 return highResCurdata; } // 计算电流单位 int16_t bms_caculate_current(uint32_t base_time) { #if CUR_FILTER_ENABLE static uint16_t dly = 0; #endif int32_t tmp, tmp1, current ,volval = 0; CurProp *prop; if (cur_item.channel < kCurChannel_End) { prop = &cur_item.prop[cur_item.channel]; switch (prop->type) { case kCurSensor_Shunt: // 分流器 cur_hv_item.cur_volt_avg / cur_prop.shunt_volt * cur_prop.cur_scale; //current = (int32_t)cur_hv_item.value[kAdIc_Cur] * prop->scale / cur_item.shunt_volt; current = HighResCurTrans(cur_hv_item.value[kAdIc_Cur]); break; case kCurSensor_SigHall: // 霍尔电流 tmp = bms_get_adc_data(kAdcData_Hall1); if(tmp<20)tmp = 0; volval = tmp * 3300 /4095; //current = (int32_t)(tmp - 250000) * prop->scale / cur_item.swing_volt; current = tmp; break; case kCurSensor_DualHall: // 霍尔电流 tmp = bms_get_adc_data(kAdcData_Hall1); volval = tmp * 3300 /4095; //current = (int32_t)(tmp - 250000) * prop->scale / cur_item.swing_volt; current = tmp; if (KIT_ABS(current) > (int32_t)prop->scale * 90) { tmp = bms_get_adc_data(kAdcData_Hall2); //current = (int32_t)(tmp - 250000) * cur_item.prop[1].scale / cur_item.swing_volt; current = tmp; } break; case kCurSensor_SigHall_Base: // 单量程带基准 tmp = bms_get_adc_data(kAdcData_Hall1); tmp1 = bms_get_adc_data(kAdcData_Hall2); current = (int32_t)(tmp - tmp1) * prop->scale / cur_item.swing_volt; break; default: break; } } //测试用 SFJ 7.30 current = volval * 100 / 10; // 电流方向 current *= prop->dir; // 零点偏移 current -= prop->offset; // 零点滤波 if (KIT_ABS(current) < prop->filter) { current = 0; } current = (int64_t)current * get_eeprom_data(kEep_Hall1CalFactor, kEepromDataType_Full) / 1000; //调试 bms_integral_soc(current, base_time); cur_hv_item.current = current / 10;//转为 0.1 #if CUR_FILTER_ENABLE dly += base_time; if (dly >= 500) { dly = 0; cur_hv_item.filter_current[cur_hv_item.filter_pos] = cur_hv_item.current; if (++cur_hv_item.filter_pos >= MCP3208_SAMPLE_CNT) { cur_hv_item.filter_pos = 0; } cur_hv_item.show_current = kit_get_avg_filter_max_min(cur_hv_item.filter_current, MCP3208_SAMPLE_CNT) * cur_item.chg_cur_dir; } #else cur_hv_item.show_current = cur_hv_item.current * cur_item.chg_cur_dir; #endif return current; } uint32_t HighVolTrans(uint16_t voldata) { // 10M 16.5K float Rsense = 10000; float Rvol = 16.5; uint32_t highvoldata = 0; highvoldata = voldata * (Rsense + Rvol) / Rvol; return highvoldata; } AdjustValue adIc_adjust_value[kAdIc_End]; uint16_t adIc_reg_map[kAdIc_End] = {MAN_Ch_0, MAN_Ch_1, MAN_Ch_2, MAN_Ch_3, MAN_Ch_4}; void get_ad_sample(void) { static uint16_t outputdata[16] = {0}; int32_t i =0; uint16_t ad =0; //auto scan mode drv_enter_auto_rst_mode_Data(outputdata, 6); for (i = 0; i < kAdIc_End; i++) { //ad = drv_get_ads8688_ch_data(adIc_reg_map[i]); cur_hv_item.ad_buf[i][cur_hv_item.ad_buf_pos[i]++] = drv_ads8688_value(outputdata[i]); ad = cur_hv_item.ad_avg[i] = kit_get_int32_avg_filter_max_min(cur_hv_item.ad_buf[i], ADCIC_SAMPLE_CNT); if (i == kAdIc_HvIso) { //cur_hv_item.value[i] = HighVolTrans2(ad)/100; bms_set_iso_volt_ad(kIsoVolt_Other, ad); } if(i == kAdIc_HvIsoNagtive) { } if (i == kAdIc_HvBat) { cur_hv_item.value[i] = (ad / 100) * 512 * 10 / (0x01 << 16); //单位是mv bms_set_iso_volt_ad(kIsoVolt_TotalVolt, cur_hv_item.value[i]); } if(i == kAdIc_Hv1) { cur_hv_item.value[i] = (ad / 100) * 512 * 10 / (0x01 << 16); //单位是mv } if(i == kAdIc_Cur) { ad = ad - adIc_adjust_value[i].zero; ad = (10 * ad / 82000) * 512 * 1000/ (0x01 << 16); //单位是mv // 防止eeprom中没有设置电压校准系数 if (get_eeprom_data(kEep_Volt1CalFactor, kEepromDataType_Full) <= 900 || get_eeprom_data(kEep_Volt1CalFactor, kEepromDataType_Full) >= 1100) { bsp_eeprom_save_data(kEep_Volt1CalFactor, 1000, kEepromDataType_Full); } cur_hv_item.value[i] = ad / 1000 * adIc_adjust_value[i].rate *get_eeprom_data(kEep_Volt1CalFactor, kEepromDataType_Full) / 1000;//转为V } if (cur_hv_item.ad_buf_pos[i] >= ADCIC_SAMPLE_CNT) { cur_hv_item.ad_buf_pos[i] = 0; } } } int16_t bms_poll_cur_hv(uint32_t base_time) { get_ad_sample(); return bms_caculate_current(base_time); } // A int16_t bms_get_current(void) { return cur_hv_item.current; } // 单位0.01A/bit void bms_set_current(int32_t cur) { cur_hv_item.can_current = cur; } void bms_set_current_channel(CurChannel channel) { if (channel < kCurChannel_End) { cur_item.channel = channel; } } int16_t bms_get_show_current(void) { return cur_hv_item.show_current; } // V int16_t bms_get_high_volt(HvType type) { int16_t tmp = 0; KIT_ASSERT_PARAM(type < kHvType_End); if (type < kHvType_End) { tmp = cur_hv_item.value[type]; } return tmp; } void bms_set_high_volt(HvType type, uint16_t value) { KIT_ASSERT_PARAM(type < kHvType_End); if ((cur_hv_item.is_simulate == false) && (type < kHvType_End)) { cur_hv_item.value[type + 3] = value; } } void bms_set_sim_high_volt(HvType type, uint16_t value) { KIT_ASSERT_PARAM(type < kHvType_End); if (type < kHvType_End) { cur_hv_item.is_simulate = true; cur_hv_item.value[type] = value; } } bool bms_is_high_volt_sim(void) { return cur_hv_item.is_simulate; } uint16_t bms_get_en_temp(EnTemp idx) { uint16_t tmp = 0; if (idx < kEnTemp_End) { tmp = cur_hv_item.en_temp[idx]; } return tmp; } void bms_set_en_temp(EnTemp idx, uint16_t temp) { if (idx < kEnTemp_End) { cur_hv_item.en_temp[idx] = temp; } } const uint32_t adIc_default_rate[kAdIc_End] = {1, 1, 1, 1, 1}; // void bms_init_cur_hv(void) { static uint8_t errcnt = 0; uint32_t i = 0, cnt = 30; #ifdef ADS_8688_EN while(drv_ads8688_Init() && errcnt < 30) { errcnt++; OSTimeDly(20); } for (i = 0; i < kAdIc_End; i++) { adIc_adjust_value[i].zero = 0; adIc_adjust_value[i].rate = adIc_default_rate[i]; } #endif // 填充buf for (i = 0; i < cnt; i++) { bms_poll_adc(10); // 时间参数为0,防止时间增加误校准SOC bms_poll_cur_hv(0); bsp_task_delay_ms(100); } bms_init_current(); }