/********************************************************************* * INCLUDES */ #include "hal_battery.h" /********************************************************************* * DEFINITIONS */ #if BATTERY_CAPACITY ==0 #define BAT_100_P 4100 #define BAT_90_P 4030 #define BAT_80_P 3930 #define BAT_70_P 3880 #define BAT_60_P 3820 #define BAT_50_P 3720 #define BAT_40_P 3650 #define BAT_30_P 3610 #define BAT_20_P 3540 #define BAT_10_P 3450 #define BAT_0_P 3200 #elif BATTERY_CAPACITY ==1 //#define BAT_100_P 4150 //#define BAT_90_P 3980 //#define BAT_80_P 3930 //#define BAT_70_P 3880 //#define BAT_60_P 3830 //#define BAT_50_P 3800 //#define BAT_40_P 3770 //#define BAT_30_P 3740 //#define BAT_20_P 3700 //#define BAT_10_P 3670 //#define BAT_0_P 3200 #define BAT_100_P 4150 #define BAT_90_P 4040 #define BAT_80_P 4000 #define BAT_70_P 3940 #define BAT_60_P 3870 #define BAT_50_P 3840 #define BAT_40_P 3800 #define BAT_30_P 3760 #define BAT_20_P 3720 #define BAT_10_P 3670 #define BAT_0_P 3200 #endif #define ADC_REF_VOLTAGE_IN_MILLIVOLTS 600 /**< Reference voltage (in milli volts) used by ADC while doing conversion. */ #define ADC_PRE_SCALING_COMPENSATION 6 /**< The ADC is configured to use VDD with 1/3 prescaling as input. And hence the result of conversion is to be multiplied by 3 to get the actual value of the battery voltage.*/ #define ADC_RES_10BIT 4096 /**< Maximum digital value for 10-bit ADC conversion. */ // VP = (RESULT * REFERENCE / 2^10) * 6 #define ADC_RESULT_IN_MILLI_VOLTS(ADC_VALUE)\ ((((ADC_VALUE) * ADC_REF_VOLTAGE_IN_MILLIVOLTS) / ADC_RES_10BIT) * ADC_PRE_SCALING_COMPENSATION) /********************************************************************* * LOCAL VARIABLES */ const int16_t filterLen = 100; static uint8_t vol = 0; static uint8_t displayvol = 0,SourceDisplayvol =0 ; static uint32_t displaytim=0; static int16_t real_battery =0; /********************************************************************* * LOCAL FUNCTIONS */ static void Bubble_int16(int16_t a[],int16_t m) { //冒泡排序 int16_t i,j; int16_t t; for(i=0;ia[j+1]){//后一位数比前一位数小的话,就交换两个数的位置(升序) t=a[j+1]; a[j+1]=a[j]; a[j]=t; } } } } static int16_t MediumFilter(int16_t val) { static int16_t filterArr[filterLen]; static int16_t filterDex = 0; static int16_t res = 0; filterArr[filterDex] = val; if(++filterDex>=filterLen){filterDex = 0; // SEGGER_RTT_printf(0,"filterArr:"); for(int i=0;i= 4170){//恒压 #elif BATTERY_CAPACITY == 1 if(batteryVoltage >= 4200){//恒压 #endif if(full_charge_temp < 0xFFFFFFFF)full_charge_temp += interval_time_MS; switch(behind_vol){ case 100: batteryVoltage = BAT_100_P+20; break; case 90: if(full_charge_temp/1000 > henyatime){ full_charge_temp =0; batteryVoltage = BAT_100_P+20; behind_vol = 100; henyatime = 0; } else batteryVoltage = BAT_90_P+20; break; case 80: if(full_charge_temp/1000 > henyatime){ behind_vol = 90; batteryVoltage = BAT_90_P+20; #if BATTERY_CAPACITY == 0 henyatime = 160; #elif BATTERY_CAPACITY == 1 henyatime = 220; #endif SEGGER_RTT_printf(0,"henya:%d,%d,%d\n",behind_vol,henyatime,full_charge_temp); full_charge_temp =0; } else batteryVoltage = BAT_80_P+20; break; case 70: if(full_charge_temp/1000 > henyatime){ batteryVoltage = BAT_80_P+20; behind_vol = 80; #if BATTERY_CAPACITY == 0 henyatime = 140; #elif BATTERY_CAPACITY == 1 henyatime = 200; #endif SEGGER_RTT_printf(0,"henya:%d,%d,%d\n",behind_vol,henyatime,full_charge_temp); full_charge_temp =0; } else batteryVoltage = BAT_70_P+20; break; default: if(full_charge_temp/1000 > henyatime){ batteryVoltage = BAT_70_P+20; behind_vol = 70; #if BATTERY_CAPACITY == 0 henyatime = 60; #elif BATTERY_CAPACITY == 1 henyatime = 90; #endif SEGGER_RTT_printf(0,"henya:%d,%d,%d\n",behind_vol,henyatime,full_charge_temp); full_charge_temp =0; } else batteryVoltage = BAT_60_P+20; break; } }else{//恒流 full_charge_temp =0; #if BATTERY_CAPACITY == 0 if(batteryVoltage >= 3810)batteryVoltage -= 320; else if(batteryVoltage < 3810 && batteryVoltage >= BAT_0_P)batteryVoltage -= 400; #elif BATTERY_CAPACITY == 1 if(batteryVoltage >= 3900)batteryVoltage -= 310; else if(batteryVoltage >= BAT_0_P)batteryVoltage -= 400; #endif else if(batteryVoltage < BAT_0_P)batteryVoltage = BAT_0_P; } } else full_charge_temp =0; bat_cal = batteryVoltage; return bat_cal; } static uint8_t GetBatteryPersent(int16_t batteryVoltage) { uint8_t vol_t = 0; if(batteryVoltage >= BAT_100_P)vol_t = 100; else if(batteryVoltage >= BAT_90_P)vol_t = 90; else if(batteryVoltage >= BAT_80_P)vol_t = 80; else if(batteryVoltage >= BAT_70_P)vol_t = 70; else if(batteryVoltage >= BAT_60_P)vol_t = 60; else if(batteryVoltage >= BAT_50_P)vol_t = 50; else if(batteryVoltage >= BAT_40_P)vol_t = 40; else if(batteryVoltage >= BAT_30_P)vol_t = 30; else if(batteryVoltage >= BAT_20_P)vol_t = 20; else if(batteryVoltage >= BAT_10_P)vol_t = 10; else if(batteryVoltage < BAT_10_P && batteryVoltage >= BAT_0_P)vol_t = ((batteryVoltage-BAT_0_P)/((BAT_10_P - BAT_0_P)/10)); else if(batteryVoltage < BAT_0_P)vol_t = 0; return vol_t; } static void cb_batteryWakeup(uint32_t t) { nrf_gpio_cfg_output(PIN_ADC_EN); nrf_gpio_pin_write(PIN_ADC_EN,0); } static void cb_batterySleep(uint32_t t) { nrf_gpio_cfg_output(PIN_ADC_EN); nrf_gpio_pin_write(PIN_ADC_EN,1); } /********************************************************************* * PUBLIC FUNCTIONS */ int16_t ADC_GetValue(uint32_t channel) { int16_t temp=0; ADC_Read(channel, &temp); return temp; } /********************************************************** * 函数名字:GetBatteryCurrentPersen * 函数作用:获取电池电量百分比 * 函数参数:adcvalue :读取到ADC值 * 函数返回值:电量值 ***********************************************************/ uint8_t Battery_GetBatteryPersent(void) { return displayvol; } void displayvol_process(void){ uint32_t charge_state_c =0; charge_state_c = nrf_gpio_pin_read(PIN_POWER_EN); if(charge_state_c){ if(SourceDisplayvol > displayvol){ if(displayvol >=10 && displayvol < 100){ if(TIME_GetTicks()-displaytim >= 2000){ displaytim = TIME_GetTicks(); displayvol+=1; SEGGER_RTT_printf(0,"1 displayvol_process:%d,%d,%d\n",SourceDisplayvol,displayvol,vol); } } else if(displayvol < 10){ if(TIME_GetTicks()-displaytim >= 2000){ displaytim = TIME_GetTicks(); displayvol+=1; SEGGER_RTT_printf(0,"2 displayvol_process:%d,%d,%d\n",SourceDisplayvol,displayvol,vol); } } } } else{ if(SourceDisplayvol < displayvol){ if(TIME_GetTicks()-displaytim >= 60000){ displaytim = TIME_GetTicks(); if(displayvol > 10 && displayvol <= 100)displayvol -= 10; else if(displayvol <= 10 && displayvol >0)displayvol -=1; SEGGER_RTT_printf(0,"3 displayvol_process:%d,%d,%d\n",SourceDisplayvol,displayvol,vol); } } } } uint8_t Battery_BatteryIs_0(void) { if(real_battery <= BAT_0_P)return 1; else return 0; } void battery_process(void) { static uint32_t tim=0; static uint32_t tim_charge=100; int16_t batteryVoltage; int16_t adcVal; int16_t volTemp; displayvol_process(); if(TIME_GetTicks()-tim >= tim_charge){ tim = TIME_GetTicks(); if( nrf_gpio_pin_read(PIN_POWER_EN)) tim_charge = 10; else tim_charge = 100; adcVal = ADC_GetValue(PIN_ADC_CHANNEL); volTemp = ADC_RESULT_IN_MILLI_VOLTS(adcVal)*5/3; // 电池电压转换计算 batteryVoltage = MediumFilter(volTemp); real_battery = batteryVoltage; batteryVoltage = Charging_voltage_calibration(batteryVoltage,tim_charge); static uint32_t t = 0; if(t != TIME_GetTicks()/1000){ t = TIME_GetTicks()/1000; SEGGER_RTT_printf(0,"%d,%d,%d,%d,%d\n",adcVal,volTemp,batteryVoltage,displayvol,t); } vol = GetBatteryPersent(batteryVoltage); if(SourceDisplayvol != vol){ SourceDisplayvol = vol; displaytim = TIME_GetTicks(); } static uint8_t vol_temp =0; if(vol_temp != displayvol){ vol_temp =displayvol; SEGGER_RTT_printf(0,"&&&&&&&&&&>vol:%d(%d),tim:%d\n\n\n",batteryVoltage,displayvol,TIME_GetTicks()/1000); } } } void Battery_Initialize(void) { ADC_SetPinChannel(PIN_ADC_IN, PIN_ADC_CHANNEL); Process_Start(0,battery_process); Wakeup_Regist(cb_batteryWakeup); Sleep_Regist(cb_batterySleep); } /********************************************************** * 函数名字:User_SAADC_DisOrEnable * 函数作用:SAADC的打开和关闭 * 函数参数:无 * 函数返回值:无 ***********************************************************/ void Battery_Enable(bool value) { static bool battery_Open_Flag =false; int16_t batteryVoltage; if(value == battery_Open_Flag)return; if(value){ nrf_gpio_cfg_output(PIN_ADC_EN); nrf_gpio_pin_write(PIN_ADC_EN,0); for(int i=0;i