forked from gary/BCU
2
0
Fork 0
BCU/app/stm32fxxx_app/app/hv_adc_manager.c

508 lines
12 KiB
C
Raw Normal View History

2024-11-26 15:52:49 +08:00
#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"
2025-02-06 15:08:48 +08:00
//#include "drv_mcp3208.h"
#include "drv_ads8688.h"
2024-11-26 15:52:49 +08:00
#define CUR_FILTER_ENABLE (0u)
2025-02-15 19:57:30 +08:00
#define ADCIC_SAMPLE_CNT (20u)
#define MCP3208_SAMPLE_CNT (10u)
2024-11-26 15:52:49 +08:00
2025-02-06 15:08:48 +08:00
ADS8688_STATIC_INIT(ads8688, kSpiDev_2, kGpioType_ADC_Cs);
2024-11-26 15:52:49 +08:00
typedef enum
{
2025-02-06 15:08:48 +08:00
kAdIc_Hv1,
kAdIc_HvBat,
kAdIc_Cur,
kAdIc_HvIso,
kAdIc_HvIsoNagtive,
kAdIc_End
} AdIcEnum;
2024-11-26 15:52:49 +08:00
typedef struct
{
bool is_simulate;
uint8_t filter_pos;
2025-02-06 15:08:48 +08:00
uint8_t ad_buf_pos[kAdIc_End];
2024-11-26 15:52:49 +08:00
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
2025-02-06 15:08:48 +08:00
int32_t value[kAdIc_End];
int32_t ad_avg[kAdIc_End];
int32_t ad_buf[kAdIc_End][ADCIC_SAMPLE_CNT];
2024-11-26 15:52:49 +08:00
} 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倍,分流器量程 乘了 10
2024-11-26 15:52:49 +08:00
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)
2024-11-26 15:52:49 +08:00
{
case kCurSensor_Shunt:
// 分流器 cur_hv_item.cur_volt_avg / cur_prop.shunt_volt * cur_prop.cur_scale;
2025-02-15 19:57:30 +08:00
current = (int32_t)cur_hv_item.value[kAdIc_Cur] * prop->scale / cur_item.shunt_volt;
//current = HighResCurTrans(cur_hv_item.value[kAdIc_Cur]);
2024-11-26 15:52:49 +08:00
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,2-18,注释
//current = volval * 100 / 10;
2024-11-26 15:52:49 +08:00
// 电流方向
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;
}
2025-02-06 15:08:48 +08:00
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};
2025-03-01 16:33:40 +08:00
uint16_t zero_calc(uint16_t value)
{
if(value > 32700 && value < 32788)
{
return 0;
}
else if(value < 20)
{
return 0;
}
else
{
return value;
}
}
2024-11-26 15:52:49 +08:00
void get_ad_sample(void)
{
2025-02-06 15:08:48 +08:00
static uint16_t outputdata[16] = {0};
2025-03-01 16:33:40 +08:00
int32_t i =0,dir = 1;
//uint16_t ad =0;
uint16_t ad = 0,value = 0;
2025-02-15 19:57:30 +08:00
#if ADC_AUTO_MODE
//auto scan mode
drv_enter_auto_rst_mode_Data(outputdata, 6);
#else
2025-03-01 16:33:40 +08:00
2025-02-15 19:57:30 +08:00
outputdata[i] = drv_get_ads8688_ch_data(MAN_Ch_0);
2025-03-01 16:33:40 +08:00
i += 1;
outputdata[i] = drv_get_ads8688_ch_data(MAN_Ch_1);
i += 1;
outputdata[i] = drv_get_ads8688_ch_data(MAN_Ch_2);
i += 1;
outputdata[i] = drv_get_ads8688_ch_data(MAN_Ch_3);
i += 1;
outputdata[i] = drv_get_ads8688_ch_data(MAN_Ch_4);
i += 1;
outputdata[i] = drv_get_ads8688_ch_data(MAN_Ch_5);
i += 1;
2025-02-15 19:57:30 +08:00
#endif
2025-02-06 15:08:48 +08:00
for (i = 0; i < kAdIc_End; i++)
2024-11-26 15:52:49 +08:00
{
2025-02-06 15:08:48 +08:00
//ad = drv_get_ads8688_ch_data(adIc_reg_map[i]);
2025-03-01 16:33:40 +08:00
//0漂处理
if(i == kAdIc_Cur)
{
outputdata[i] = zero_calc(outputdata[i]);
}
2025-02-06 15:08:48 +08:00
cur_hv_item.ad_buf[i][cur_hv_item.ad_buf_pos[i]++] = drv_ads8688_value(outputdata[i]);
2025-03-01 16:33:40 +08:00
cur_hv_item.ad_avg[i] = kit_get_int32_avg_filter_max_min(cur_hv_item.ad_buf[i], ADCIC_SAMPLE_CNT);
2025-02-06 15:08:48 +08:00
2025-03-01 16:33:40 +08:00
if(cur_hv_item.ad_avg[i] < 0)
{
dir = -1;
}
ad = KIT_ABS(cur_hv_item.ad_avg[i]);
2025-02-06 15:08:48 +08:00
if (i == kAdIc_HvIso)
{
//cur_hv_item.value[i] = HighVolTrans2(ad)/100;
2025-03-01 16:33:40 +08:00
bms_set_iso_volt_ad(kIsoVolt_Other, dir * ad);
2025-02-06 15:08:48 +08:00
}
if(i == kAdIc_HvIsoNagtive)
{
}
if (i == kAdIc_HvBat)
{
2025-03-01 16:33:40 +08:00
cur_hv_item.value[i] = dir * (376 * ad * 512 * 10 / (0x01 << 15)) / 100; //单位是mv
2025-02-06 15:08:48 +08:00
bms_set_iso_volt_ad(kIsoVolt_TotalVolt, cur_hv_item.value[i]);
}
if(i == kAdIc_Hv1)
{
2025-03-01 16:33:40 +08:00
cur_hv_item.value[i] = dir * (376 * ad * 512 * 10 / (0x01 << 15)) / 100; //单位是mv
2025-02-06 15:08:48 +08:00
}
if(i == kAdIc_Cur)
{
2025-03-01 16:33:40 +08:00
//ad = ad - adIc_adjust_value[i].zero;
//ad = (ad * 5120 * 10 / (0x01 << 15)) / 82; //单位是mv
ad = (ad * 2560 * 10 * 100 / (0x01 << 15)) / 82; //单位是0.1 mv
2025-02-06 15:08:48 +08:00
// 防止eeprom中没有设置电压校准系数
if (get_eeprom_data(kEep_Volt1CalFactor, kEepromDataType_Full) <= 900 || get_eeprom_data(kEep_Volt1CalFactor, kEepromDataType_Full) >= 1100)
2024-11-26 15:52:49 +08:00
{
2025-02-06 15:08:48 +08:00
bsp_eeprom_save_data(kEep_Volt1CalFactor, 1000, kEepromDataType_Full);
2024-11-26 15:52:49 +08:00
}
2025-03-01 16:33:40 +08:00
cur_hv_item.value[i] = ad * dir;/// 1000 * adIc_adjust_value[i].rate *get_eeprom_data(kEep_Volt1CalFactor, kEepromDataType_Full) / 1000;//转为V
2025-02-06 15:08:48 +08:00
}
2024-11-26 15:52:49 +08:00
2025-02-06 15:08:48 +08:00
if (cur_hv_item.ad_buf_pos[i] >= ADCIC_SAMPLE_CNT)
{
cur_hv_item.ad_buf_pos[i] = 0;
}
2024-11-26 15:52:49 +08:00
}
}
int16_t bms_poll_cur_hv(uint32_t base_time)
2025-02-06 15:08:48 +08:00
{
2024-11-26 15:52:49 +08:00
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;
}
}
2025-02-06 15:08:48 +08:00
const uint32_t adIc_default_rate[kAdIc_End] = {1, 1, 1, 1, 1};
2024-11-26 15:52:49 +08:00
2025-02-06 15:08:48 +08:00
//
2024-11-26 15:52:49 +08:00
void bms_init_cur_hv(void)
{
2025-02-12 15:02:26 +08:00
static uint8_t errcnt = 0;
2024-11-26 15:52:49 +08:00
uint32_t i = 0, cnt = 30;
2025-02-06 15:08:48 +08:00
#ifdef ADS_8688_EN
2025-02-12 15:02:26 +08:00
while(drv_ads8688_Init() && errcnt < 30)
2025-02-06 15:08:48 +08:00
{
2025-02-12 15:02:26 +08:00
errcnt++;
2025-02-06 15:08:48 +08:00
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
2024-11-26 15:52:49 +08:00
// 填充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();
}