| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- #include "iv_measure.h"
- #include "bsp/ml5238.h"
- #include "bsp/cs1180.h"
- #include "bsp/gd32_adc.h"
- #include "bsp/clock.h"
- #include "bsp/gpio.h"
- #include "bsp/temp_lookup_tab.h"
- /* measure the temp & current & voltage for battery pack by using
- * ms5238 & cs1180(only used when bms is in small current loading)
- */
- /* this is the inited gain set to the ms5238, but the really gain is calibrated
- * by measure_system_calibrate
- */
- static float imon_gain_10x = 10.0f;
- static float imon_gain_50x = 50.0f;
- static float imon_gain_now;
- static float vim0_10x = 0.0f;
- static float vim0_50x = 0.0f;
- static float vim0_now;
- #if defined CONFIG_BOARD_SP700
- #define r_resistor 1.0f // 1ºÁÅ·
- #elif defined CONFIG_BOARD_SP600
- #define r_resistor 2.0f
- #endif
- #define r_pcb_resistor 0.0f // pcb resistor
- static const float r_sense = r_resistor + r_pcb_resistor;
- static const float v_ref = 3300.0f; //adc ref = 3.3v
- static const float max_adc = 65535.0f;
- static const float small_cur_r_sense = 360.0f;//mo
- static void __inline__ select_gain_10x(int select){
- if (select){
- ML5238_IMON_OUT_10X();
- imon_gain_now = imon_gain_10x;
- vim0_now = vim0_10x;
- }else {
- ML5238_IMON_OUT_50X();
- imon_gain_now = imon_gain_50x;
- vim0_now = vim0_50x;
- }
- }
- static int __inline__ _is_x10_gain(void){
- return imon_gain_now == imon_gain_10x;
- }
- /*calibrate when startup && temperature is changed more than 5? degree
- * calibrate the ms5238's IMON output voltage gain
- */
- void current_calibrate(void){
- /* calibrate the 10x gain */
- ML5238_IMON_OUT_ZERO_10X();
- vim0_10x = adc_sample(ADC_CHAN_IMON ,TRUE);
- ML5238_IMON_OUT_V2000_10X();
- float vim1 = adc_sample(ADC_CHAN_IMON, FALSE);
- ML5238_IMON_OUT_V100_10X();
- float vr = adc_sample(ADC_CHAN_IMON, FALSE);
- imon_gain_10x = ML5238_GAIN(vim0_10x, vim1, vr);
- /* calibrate the 50x gain */
- ML5238_IMON_OUT_ZERO_50X();
- vim0_50x = adc_sample(ADC_CHAN_IMON ,TRUE);
- ML5238_IMON_OUT_V2000_50X();
- vim1 = adc_sample(ADC_CHAN_IMON, FALSE);
- ML5238_IMON_OUT_V100_50X();
- vr = adc_sample(ADC_CHAN_IMON, FALSE);
- imon_gain_50x = ML5238_GAIN(vim0_50x, vim1, vr);
- select_gain_10x(0);//default gain is 50x, if 50x overflow, use 10x
- }
- void measure_system_init(void){
- adc_init();
- ml5238_init();
- //cs1180_init();
- current_calibrate();
- }
- /* get battery pack's current (mA) */
- float get_imon_current(void){
- float adc = adc_sample(ADC_CHAN_IMON, TRUE);
- if (adc >= 0xFFF0 && (!_is_x10_gain())){//overflow, use 10x gain
- select_gain_10x(1);
- adc = adc_sample(ADC_CHAN_IMON, TRUE);
- }else if (adc <= 0x1F && (_is_x10_gain())){// is too small, select 50x gain
- select_gain_10x(0);
- adc = adc_sample(ADC_CHAN_IMON, TRUE);
- }
- float cali_adc = ML5238_V_RSENSER(adc, vim0_now, imon_gain_now);
- return (cali_adc / max_adc) * v_ref / r_sense * 1000;
- }
- /* get cell's voltage (mV) */
- float get_vmon_voltage(int cell){
- ml5238_select_cell_to_vmon(cell);
- delay_us(100);
- float adc = adc_sample(ADC_CHAN_VMON, TRUE);
- return cell_real_vol((adc / max_adc) * v_ref);
- }
- /* get battery pack's aux current (mA) */
- float get_small_current(void){
- float adc = adc_sample(ADC_CHAN_AUX_CURR, TRUE);
- return (adc / max_adc * v_ref) / small_cur_r_sense * 1000;
- }
- int get_pcb_temperature(void){
- TEMP_OPEN(1);
- delay_us(100);
- uint16_t adc = adc_sample(ADC_CHAN_TEMPERATURE_4, TRUE);
- TEMP_OPEN(0);
- return get_temp_by_adc(adc);
- }
- /*
- * index : 0...2
- */
- int get_pack_temperature(int index){
- TEMP_OPEN(1);
- delay_us(100);
- uint16_t adc = adc_sample(ADC_CHAN_TEMPERATURE_1 + index, TRUE);
- TEMP_OPEN(0);
- return get_temp_by_adc(adc);
- }
|