123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378 |
- /*********************************************************************
- * 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;i<m-1;i++){//n个数的数列总共扫描n-1次
- for(j=0;j<m-i-1;j++){//每一趟扫描到a[n-i-2]与a[n-i-1]比较为止结束
- if(a[j]>a[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<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;
- }
- static int16_t Charging_voltage_calibration(int16_t batteryVoltage,uint8_t interval_time_MS){
-
- uint32_t charge_state_c =0;
- static uint32_t full_charge_temp = 0;
- static uint32_t chargechange = 0;
- static uint16_t henyatime = 0;
- int16_t bat_cal =0;
- static uint8_t behind_vol = 0;
-
- charge_state_c = nrf_gpio_pin_read(PIN_POWER_EN);
- if(chargechange != charge_state_c){//插入充电,跳变
- chargechange = charge_state_c;
- if(charge_state_c){
- full_charge_temp =0 ;
- #if BATTERY_CAPACITY == 0
- if(vol <= 70)henyatime = 60;
- else if(vol == 80)henyatime = 140;
- else if(vol == 90)henyatime = 162;
- else if(vol == 100)henyatime = 0;
- #elif BATTERY_CAPACITY == 1
- if(vol <= 70)henyatime = 90;
- else if(vol == 80)henyatime = 200;
- else if(vol == 90)henyatime = 220;
- else if(vol == 100)henyatime = 0;
- #endif
- behind_vol = vol;
- SEGGER_RTT_printf(0,"Charging_voltage_calibration %d,%d\n",vol,henyatime);
- }
- }
- if(charge_state_c){
- #if BATTERY_CAPACITY == 0
- if(batteryVoltage >= 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<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);
- batteryVoltage = Charging_voltage_calibration(batteryVoltage,0);
- vol = GetBatteryPersent(batteryVoltage);
- displayvol = vol;
- SourceDisplayvol = vol;
-
- SEGGER_RTT_printf(0,"Battery_Enable,%d,%d,%d\n",batteryVoltage,vol,displayvol);
-
- }else{
- nrf_gpio_cfg_output(PIN_ADC_EN); nrf_gpio_pin_write(PIN_ADC_EN,1);
- }
- battery_Open_Flag = value;
- }
|