123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348 |
- /*********************************************************************
- * INCLUDES
- */
- #include "usr_config.h"
- #include "hal_battery.h"
- #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. */
- #define ADC_RESULT_IN_MILLI_VOLTS(ADC_VALUE)\
- ((((ADC_VALUE) * ADC_REF_VOLTAGE_IN_MILLIVOLTS) / ADC_RES_10BIT) * ADC_PRE_SCALING_COMPENSATION)
- static void Bubble_int16(int16_t a[],int16_t m)
- {
- int16_t i,j,t;
- for(i=0;i<m-1;i++){
- for(j=0;j<m-i-1;j++){
- if(a[j]>a[j+1]){
- t=a[j+1];
- a[j+1]=a[j];
- a[j]=t;
- }
- }
- }
- }
- const int16_t filterLen = 100;
- 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<filterLen;i++){SEGGER_RTT_printf(0,"%d,",filterArr[i]);} SEGGER_RTT_printf(0,"\n");
- Bubble_int16(filterArr,filterLen);
- // SEGGER_RTT_printf(0,"filterArr:"); for(int i=0;i<filterLen;i++){SEGGER_RTT_printf(0,"%d,",filterArr[i]);} SEGGER_RTT_printf(0,"\n");
- res = filterArr[filterLen/2];
- }
- return res;
- }
- typedef struct _bat_t{
- uint8_t vol_filter ;//过滤之后真实的电压百分比
- int16_t vol_value; //过滤之后的ADC值
- uint8_t displayvol;//App显示的电压百分比
- uint8_t Displayvol_s;//App端需要调整到的电压百分比
- uint32_t display_t;//显示的时间记录
- uint8_t behind_vol;//开始充电前的电压百分比
- }bat_t;
- static bat_t mIBAT_T={0,0,0,0,0};
- uint8_t GetBatteryPersent(void)
- {
- if(mIBAT_T.displayvol >=10)return (mIBAT_T.displayvol/10*10);
- else return mIBAT_T.displayvol;
- }
- void displayvol_process(uint32_t charge_state_c){
- if(charge_state_c){
- if(mIBAT_T.Displayvol_s > mIBAT_T.displayvol){
- if(mIBAT_T.displayvol >=10 && mIBAT_T.displayvol < 100){
- if(TIME_GetTicks()-mIBAT_T.display_t >= 2000){
- mIBAT_T.display_t = TIME_GetTicks();
- mIBAT_T.displayvol+=1;
- SEGGER_RTT_printf(0,"1 displayvol_process:%d,%d,%d\n",mIBAT_T.Displayvol_s,mIBAT_T.displayvol,mIBAT_T.vol_filter);
- }
- }
- else if(mIBAT_T.displayvol < 10){
- if(TIME_GetTicks()-mIBAT_T.display_t >= 2000){
- mIBAT_T.display_t = TIME_GetTicks();
- mIBAT_T.displayvol+=1;
- SEGGER_RTT_printf(0,"2 displayvol_process:%d,%d,%d\n",mIBAT_T.Displayvol_s,mIBAT_T.displayvol,mIBAT_T.vol_filter);
- }
- }
- }
- }
- else{
- if(mIBAT_T.Displayvol_s < mIBAT_T.displayvol){
- if(TIME_GetTicks()-mIBAT_T.display_t >= 60000){ mIBAT_T.display_t = TIME_GetTicks();
- if(mIBAT_T.displayvol > 10 && mIBAT_T.displayvol <= 100)mIBAT_T.displayvol -= 10;
- else if(mIBAT_T.displayvol <= 10 && mIBAT_T.displayvol >0)mIBAT_T.displayvol -=1;
- SEGGER_RTT_printf(0,"3 displayvol_process:%d,%d,%d\n",mIBAT_T.Displayvol_s,mIBAT_T.displayvol,mIBAT_T.vol_filter);
- }
- }
- }
-
- }
- #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
- static const uint16_t Constant_Charge[4] ={140,280,370,0};
-
- #elif BATTERY_CAPACITY ==1
- #define BAT_100_P 4100
- #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
- static const uint16_t Constant_Charge[4] ={270,380,400,0};
- #endif
- uint8_t Battery_BatteryIs_0(void)
- {
- if(mIBAT_T.vol_value <= BAT_0_P)return 1;
- else return 0;
- }
- static int16_t Charging_voltage_calibration(int16_t batteryVoltage,uint8_t interval_time_MS,uint32_t charge_state_c){
-
- static uint32_t full_charge_temp = 0;
- static uint32_t chargechange = 0;
- static uint16_t henyatime = 0;
- int16_t bat_cal =0;
- if(chargechange != charge_state_c){//插入充电,跳变
- chargechange = charge_state_c;
- if(charge_state_c){
- full_charge_temp =0 ;
- if(mIBAT_T.behind_vol<= 70)henyatime = Constant_Charge[0];
- else if(mIBAT_T.behind_vol == 80)henyatime = Constant_Charge[1];
- else if(mIBAT_T.behind_vol == 90)henyatime = Constant_Charge[2];
- else if(mIBAT_T.behind_vol == 100)henyatime = Constant_Charge[3];
- // SEGGER_RTT_printf(0,"Charging_voltage_calibration %d,%d\n",mIBAT_T.behind_vol,henyatime);
- }
- }
- if(charge_state_c){
- #if BATTERY_CAPACITY == 0
- if(batteryVoltage >= 4100){//恒压
- #elif BATTERY_CAPACITY == 1
- if(batteryVoltage >= 4230){//恒压
- #endif
- if(full_charge_temp < 0xFFFFFFFF)full_charge_temp += interval_time_MS;
- switch(mIBAT_T.behind_vol){
- case 100:
- batteryVoltage = BAT_100_P+20;
- break;
- case 90:
- if(full_charge_temp/1000 > henyatime){SEGGER_RTT_printf(0,">>>>> 4 henya:%d,%d,%d\n",mIBAT_T.behind_vol,henyatime,full_charge_temp);
- full_charge_temp =0;
- batteryVoltage = BAT_100_P+20;
- mIBAT_T.behind_vol = 100;
- henyatime = Constant_Charge[3];
- }
- else batteryVoltage = BAT_90_P+20;
- break;
- case 80:
- if(full_charge_temp/1000 > henyatime){SEGGER_RTT_printf(0,">>>>> 3 henya:%d,%d,%d\n",mIBAT_T.behind_vol,henyatime,full_charge_temp);
- mIBAT_T.behind_vol = 90;
- batteryVoltage = BAT_90_P+20;
- henyatime = Constant_Charge[2];
- full_charge_temp =0;
- }
- else batteryVoltage = BAT_80_P+20;
- break;
- case 70:
- if(full_charge_temp/1000 > henyatime){SEGGER_RTT_printf(0,">>>>> 2 henya:%d,%d,%d\n",mIBAT_T.behind_vol,henyatime,full_charge_temp);
- batteryVoltage = BAT_80_P+20;
- mIBAT_T.behind_vol = 80;
- henyatime = Constant_Charge[1];
- full_charge_temp =0;
- }
- else batteryVoltage = BAT_70_P+20;
- break;
- default:
- if(full_charge_temp/1000 > henyatime){SEGGER_RTT_printf(0,">>>>> 1henya:%d,%d,%d\n",mIBAT_T.behind_vol,henyatime,full_charge_temp);
- batteryVoltage = BAT_70_P+20;
- mIBAT_T.behind_vol = 70;
- henyatime = Constant_Charge[0];
- full_charge_temp =0;
- }
- else batteryVoltage = BAT_60_P+20;
- break;
- }
- }else{//恒流
- full_charge_temp =0;
- mIBAT_T.behind_vol = (mIBAT_T.displayvol/10)*10;
- #if BATTERY_CAPACITY == 0
- if(batteryVoltage >= 4020)batteryVoltage -= 300;
- else if(batteryVoltage >= 3940)batteryVoltage -= 150;
- else if(batteryVoltage >= 3790)batteryVoltage -= 190;
- else if(batteryVoltage >= 3770)batteryVoltage -= 250;
- else if(batteryVoltage >= 3640)batteryVoltage -= 260;
- else if(batteryVoltage >= 3660)batteryVoltage -= 280;
- else if(batteryVoltage < 3660 && batteryVoltage >= BAT_0_P)batteryVoltage -= 300;
- #elif BATTERY_CAPACITY == 1
- if(batteryVoltage >= 4170)batteryVoltage -= 310;
- else if(batteryVoltage >= 4130)batteryVoltage -= 360;
- else if(batteryVoltage >= 4080)batteryVoltage -= 380;
- 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 Battery_UpdatePersent(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);
- }
- int16_t ADC_GetValue(uint32_t channel)
- {
- int16_t temp=0;
- ADC_Read(channel, &temp);
- return temp;
- }
- static void Battery_process(void)
- {
- int16_t batteryV;
- int16_t adcVal;
- int16_t volTemp;
- uint32_t charge_state_c =0;
-
- charge_state_c = nrf_gpio_pin_read(PIN_CHARGING);
- if(charge_state_c) Process_UpdatePeroid(Battery_process,10);
- else Process_UpdatePeroid(Battery_process,100);
- adcVal = ADC_GetValue(PIN_ADC_CHANNEL);volTemp = ADC_RESULT_IN_MILLI_VOLTS(adcVal)*5/3;// 电池电压转换计算
- mIBAT_T.vol_value = MediumFilter(volTemp);
- batteryV = Charging_voltage_calibration(mIBAT_T.vol_value,Process_GetPeroid(Battery_process),charge_state_c);//电池校准
- mIBAT_T.vol_filter = Battery_UpdatePersent(batteryV);
- // static uint32_t t = 0;
- // if(t !=TIME_GetTicks()/1000){
- // t = TIME_GetTicks()/1000;
- // SEGGER_RTT_printf(0,"%d,%d,%d,%d,%d\n",volTemp,batteryV,mIBAT_T.displayvol,mIBAT_T.Displayvol_s,t);
- // }
- if(mIBAT_T.Displayvol_s != mIBAT_T.vol_filter){
- mIBAT_T.Displayvol_s = mIBAT_T.vol_filter;
- mIBAT_T.display_t = TIME_GetTicks();
- }
- displayvol_process(charge_state_c);
- // static uint8_t vol_temp =0;
- // if(vol_temp != mIBAT_T.displayvol){
- // vol_temp =mIBAT_T.displayvol;
- // SEGGER_RTT_printf(0,"&&&&&&&&&&>mIBAT_T.vol_filter:%d(%d),tim:%d\n\n\n",batteryV,mIBAT_T.displayvol,TIME_GetTicks()/1000);
- // }
- }
- void Battery_Initialize(void)
- {
- ADC_SetPinChannel(PIN_ADC_IN, PIN_ADC_CHANNEL);
- Process_Start(100,"Battery",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<filterLen;i++){
- MediumFilter(ADC_RESULT_IN_MILLI_VOLTS(ADC_GetValue(PIN_ADC_CHANNEL))*5/3);
- }
- batteryVoltage = (ADC_RESULT_IN_MILLI_VOLTS(ADC_GetValue(PIN_ADC_CHANNEL))*5/3);
- uint32_t charge_state_c = nrf_gpio_pin_read(PIN_CHARGING);
- mIBAT_T.vol_value = batteryVoltage;
- batteryVoltage = Charging_voltage_calibration(batteryVoltage,0,charge_state_c);
- mIBAT_T.vol_filter = Battery_UpdatePersent(batteryVoltage);
- mIBAT_T.displayvol = mIBAT_T.vol_filter;
- mIBAT_T.Displayvol_s = mIBAT_T.vol_filter;
- mIBAT_T.behind_vol = mIBAT_T.vol_filter;
-
- SEGGER_RTT_printf(0,"ADC_Enable,%d,%d,%d\n",batteryVoltage,mIBAT_T.vol_filter,mIBAT_T.displayvol);
-
- }else{
- nrf_gpio_cfg_output(PIN_ADC_EN); nrf_gpio_pin_write(PIN_ADC_EN,1);
- }
- battery_Open_Flag = value;
- }
|