hal_battery_NoPowerEnPin.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. /*********************************************************************
  2. * INCLUDES
  3. */
  4. #include "usr_config.h"
  5. #include "hal_battery.h"
  6. #define ADC_REF_VOLTAGE_IN_MILLIVOLTS 600 /**< Reference voltage (in milli volts) used by ADC while doing conversion. */
  7. #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.*/
  8. #define ADC_RES_10BIT 4096 /**< Maximum digital value for 10-bit ADC conversion. */
  9. #define ADC_RESULT_IN_MILLI_VOLTS(ADC_VALUE)\
  10. ((((ADC_VALUE) * ADC_REF_VOLTAGE_IN_MILLIVOLTS) / ADC_RES_10BIT) * ADC_PRE_SCALING_COMPENSATION)
  11. static void Bubble_int16(int16_t a[],int16_t m)
  12. {
  13. int16_t i,j,t;
  14. for(i=0;i<m-1;i++){
  15. for(j=0;j<m-i-1;j++){
  16. if(a[j]>a[j+1]){
  17. t=a[j+1];
  18. a[j+1]=a[j];
  19. a[j]=t;
  20. }
  21. }
  22. }
  23. }
  24. const int16_t filterLen = 100;
  25. static int16_t MediumFilter(int16_t val)
  26. {
  27. static int16_t filterArr[filterLen];
  28. static int16_t filterDex = 0;
  29. static int16_t res = 0;
  30. filterArr[filterDex] = val;
  31. if(++filterDex>=filterLen){filterDex = 0;
  32. // SEGGER_RTT_printf(0,"filterArr:"); for(int i=0;i<filterLen;i++){SEGGER_RTT_printf(0,"%d,",filterArr[i]);} SEGGER_RTT_printf(0,"\n");
  33. Bubble_int16(filterArr,filterLen);
  34. // SEGGER_RTT_printf(0,"filterArr:"); for(int i=0;i<filterLen;i++){SEGGER_RTT_printf(0,"%d,",filterArr[i]);} SEGGER_RTT_printf(0,"\n");
  35. res = filterArr[filterLen/2];
  36. }
  37. return res;
  38. }
  39. typedef struct _bat_t{
  40. uint8_t vol_filter ;//过滤之后真实的电压百分比
  41. int16_t vol_value; //过滤之后的ADC值
  42. uint8_t displayvol;//App显示的电压百分比
  43. uint8_t Displayvol_s;//App端需要调整到的电压百分比
  44. uint32_t display_t;//显示的时间记录
  45. uint8_t behind_vol;//开始充电前的电压百分比
  46. }bat_t;
  47. static bat_t mIBAT_T={0,0,0,0,0};
  48. uint8_t GetBatteryPersent(void)
  49. {
  50. if(mIBAT_T.displayvol >=10)return (mIBAT_T.displayvol/10*10);
  51. else return mIBAT_T.displayvol;
  52. }
  53. void displayvol_process(uint32_t charge_state_c){
  54. if(charge_state_c){
  55. if(mIBAT_T.Displayvol_s > mIBAT_T.displayvol){
  56. if(mIBAT_T.displayvol >=10 && mIBAT_T.displayvol < 100){
  57. if(TIME_GetTicks()-mIBAT_T.display_t >= 2000){
  58. mIBAT_T.display_t = TIME_GetTicks();
  59. mIBAT_T.displayvol+=1;
  60. SEGGER_RTT_printf(0,"1 displayvol_process:%d,%d,%d\n",mIBAT_T.Displayvol_s,mIBAT_T.displayvol,mIBAT_T.vol_filter);
  61. }
  62. }
  63. else if(mIBAT_T.displayvol < 10){
  64. if(TIME_GetTicks()-mIBAT_T.display_t >= 2000){
  65. mIBAT_T.display_t = TIME_GetTicks();
  66. mIBAT_T.displayvol+=1;
  67. SEGGER_RTT_printf(0,"2 displayvol_process:%d,%d,%d\n",mIBAT_T.Displayvol_s,mIBAT_T.displayvol,mIBAT_T.vol_filter);
  68. }
  69. }
  70. }
  71. }
  72. else{
  73. if(mIBAT_T.Displayvol_s < mIBAT_T.displayvol){
  74. if(TIME_GetTicks()-mIBAT_T.display_t >= 60000){ mIBAT_T.display_t = TIME_GetTicks();
  75. if(mIBAT_T.displayvol > 10 && mIBAT_T.displayvol <= 100)mIBAT_T.displayvol -= 10;
  76. else if(mIBAT_T.displayvol <= 10 && mIBAT_T.displayvol >0)mIBAT_T.displayvol -=1;
  77. SEGGER_RTT_printf(0,"3 displayvol_process:%d,%d,%d\n",mIBAT_T.Displayvol_s,mIBAT_T.displayvol,mIBAT_T.vol_filter);
  78. }
  79. }
  80. }
  81. }
  82. #if BATTERY_CAPACITY ==0
  83. #define BAT_100_P 4100
  84. #define BAT_90_P 4030
  85. #define BAT_80_P 3930
  86. #define BAT_70_P 3880
  87. #define BAT_60_P 3820
  88. #define BAT_50_P 3720
  89. #define BAT_40_P 3650
  90. #define BAT_30_P 3610
  91. #define BAT_20_P 3540
  92. #define BAT_10_P 3450
  93. #define BAT_0_P 3200
  94. static const uint16_t Constant_Charge[4] ={140,280,370,0};
  95. #elif BATTERY_CAPACITY ==1
  96. #define BAT_100_P 4100
  97. #define BAT_90_P 4040
  98. #define BAT_80_P 4000
  99. #define BAT_70_P 3940
  100. #define BAT_60_P 3870
  101. #define BAT_50_P 3840
  102. #define BAT_40_P 3800
  103. #define BAT_30_P 3760
  104. #define BAT_20_P 3720
  105. #define BAT_10_P 3670
  106. #define BAT_0_P 3200
  107. static const uint16_t Constant_Charge[4] ={270,380,400,0};
  108. #endif
  109. uint8_t Battery_BatteryIs_0(void)
  110. {
  111. if(mIBAT_T.vol_value <= BAT_0_P)return 1;
  112. else return 0;
  113. }
  114. static int16_t Charging_voltage_calibration(int16_t batteryVoltage,uint8_t interval_time_MS,uint32_t charge_state_c){
  115. static uint32_t full_charge_temp = 0;
  116. static uint32_t chargechange = 0;
  117. static uint16_t henyatime = 0;
  118. int16_t bat_cal =0;
  119. if(chargechange != charge_state_c){//插入充电,跳变
  120. chargechange = charge_state_c;
  121. if(charge_state_c){
  122. full_charge_temp =0 ;
  123. if(mIBAT_T.behind_vol<= 70)henyatime = Constant_Charge[0];
  124. else if(mIBAT_T.behind_vol == 80)henyatime = Constant_Charge[1];
  125. else if(mIBAT_T.behind_vol == 90)henyatime = Constant_Charge[2];
  126. else if(mIBAT_T.behind_vol == 100)henyatime = Constant_Charge[3];
  127. // SEGGER_RTT_printf(0,"Charging_voltage_calibration %d,%d\n",mIBAT_T.behind_vol,henyatime);
  128. }
  129. }
  130. if(charge_state_c){
  131. #if BATTERY_CAPACITY == 0
  132. if(batteryVoltage >= 4100){//恒压
  133. #elif BATTERY_CAPACITY == 1
  134. if(batteryVoltage >= 4230){//恒压
  135. #endif
  136. if(full_charge_temp < 0xFFFFFFFF)full_charge_temp += interval_time_MS;
  137. switch(mIBAT_T.behind_vol){
  138. case 100:
  139. batteryVoltage = BAT_100_P+20;
  140. break;
  141. case 90:
  142. if(full_charge_temp/1000 > henyatime){SEGGER_RTT_printf(0,">>>>> 4 henya:%d,%d,%d\n",mIBAT_T.behind_vol,henyatime,full_charge_temp);
  143. full_charge_temp =0;
  144. batteryVoltage = BAT_100_P+20;
  145. mIBAT_T.behind_vol = 100;
  146. henyatime = Constant_Charge[3];
  147. }
  148. else batteryVoltage = BAT_90_P+20;
  149. break;
  150. case 80:
  151. if(full_charge_temp/1000 > henyatime){SEGGER_RTT_printf(0,">>>>> 3 henya:%d,%d,%d\n",mIBAT_T.behind_vol,henyatime,full_charge_temp);
  152. mIBAT_T.behind_vol = 90;
  153. batteryVoltage = BAT_90_P+20;
  154. henyatime = Constant_Charge[2];
  155. full_charge_temp =0;
  156. }
  157. else batteryVoltage = BAT_80_P+20;
  158. break;
  159. case 70:
  160. if(full_charge_temp/1000 > henyatime){SEGGER_RTT_printf(0,">>>>> 2 henya:%d,%d,%d\n",mIBAT_T.behind_vol,henyatime,full_charge_temp);
  161. batteryVoltage = BAT_80_P+20;
  162. mIBAT_T.behind_vol = 80;
  163. henyatime = Constant_Charge[1];
  164. full_charge_temp =0;
  165. }
  166. else batteryVoltage = BAT_70_P+20;
  167. break;
  168. default:
  169. if(full_charge_temp/1000 > henyatime){SEGGER_RTT_printf(0,">>>>> 1henya:%d,%d,%d\n",mIBAT_T.behind_vol,henyatime,full_charge_temp);
  170. batteryVoltage = BAT_70_P+20;
  171. mIBAT_T.behind_vol = 70;
  172. henyatime = Constant_Charge[0];
  173. full_charge_temp =0;
  174. }
  175. else batteryVoltage = BAT_60_P+20;
  176. break;
  177. }
  178. }else{//恒流
  179. full_charge_temp =0;
  180. mIBAT_T.behind_vol = (mIBAT_T.displayvol/10)*10;
  181. #if BATTERY_CAPACITY == 0
  182. if(batteryVoltage >= 4020)batteryVoltage -= 300;
  183. else if(batteryVoltage >= 3940)batteryVoltage -= 150;
  184. else if(batteryVoltage >= 3790)batteryVoltage -= 190;
  185. else if(batteryVoltage >= 3770)batteryVoltage -= 250;
  186. else if(batteryVoltage >= 3640)batteryVoltage -= 260;
  187. else if(batteryVoltage >= 3660)batteryVoltage -= 280;
  188. else if(batteryVoltage < 3660 && batteryVoltage >= BAT_0_P)batteryVoltage -= 300;
  189. #elif BATTERY_CAPACITY == 1
  190. if(batteryVoltage >= 4170)batteryVoltage -= 310;
  191. else if(batteryVoltage >= 4130)batteryVoltage -= 360;
  192. else if(batteryVoltage >= 4080)batteryVoltage -= 380;
  193. else if(batteryVoltage >= BAT_0_P)batteryVoltage -= 400;
  194. #endif
  195. else if(batteryVoltage < BAT_0_P)batteryVoltage = BAT_0_P;
  196. }
  197. }
  198. else full_charge_temp =0;
  199. bat_cal = batteryVoltage;
  200. return bat_cal;
  201. }
  202. static uint8_t Battery_UpdatePersent(int16_t batteryVoltage)
  203. {
  204. uint8_t vol_t = 0;
  205. if(batteryVoltage >= BAT_100_P)vol_t = 100;
  206. else if(batteryVoltage >= BAT_90_P)vol_t = 90;
  207. else if(batteryVoltage >= BAT_80_P)vol_t = 80;
  208. else if(batteryVoltage >= BAT_70_P)vol_t = 70;
  209. else if(batteryVoltage >= BAT_60_P)vol_t = 60;
  210. else if(batteryVoltage >= BAT_50_P)vol_t = 50;
  211. else if(batteryVoltage >= BAT_40_P)vol_t = 40;
  212. else if(batteryVoltage >= BAT_30_P)vol_t = 30;
  213. else if(batteryVoltage >= BAT_20_P)vol_t = 20;
  214. else if(batteryVoltage >= BAT_10_P)vol_t = 10;
  215. else if(batteryVoltage < BAT_10_P && batteryVoltage >= BAT_0_P)vol_t = ((batteryVoltage-BAT_0_P)/((BAT_10_P - BAT_0_P)/10));
  216. else if(batteryVoltage < BAT_0_P)vol_t = 0;
  217. return vol_t;
  218. }
  219. static void cb_batteryWakeup(uint32_t t)
  220. {
  221. nrf_gpio_cfg_output(PIN_ADC_EN); nrf_gpio_pin_write(PIN_ADC_EN,0);
  222. }
  223. static void cb_batterySleep(uint32_t t)
  224. {
  225. nrf_gpio_cfg_output(PIN_ADC_EN); nrf_gpio_pin_write(PIN_ADC_EN,1);
  226. }
  227. int16_t ADC_GetValue(uint32_t channel)
  228. {
  229. int16_t temp=0;
  230. ADC_Read(channel, &temp);
  231. return temp;
  232. }
  233. static void Battery_process(void)
  234. {
  235. int16_t batteryV;
  236. int16_t adcVal;
  237. int16_t volTemp;
  238. uint32_t charge_state_c =0;
  239. charge_state_c = nrf_gpio_pin_read(PIN_CHARGING);
  240. if(charge_state_c) Process_UpdatePeroid(Battery_process,10);
  241. else Process_UpdatePeroid(Battery_process,100);
  242. adcVal = ADC_GetValue(PIN_ADC_CHANNEL);volTemp = ADC_RESULT_IN_MILLI_VOLTS(adcVal)*5/3;// 电池电压转换计算
  243. mIBAT_T.vol_value = MediumFilter(volTemp);
  244. batteryV = Charging_voltage_calibration(mIBAT_T.vol_value,Process_GetPeroid(Battery_process),charge_state_c);//电池校准
  245. mIBAT_T.vol_filter = Battery_UpdatePersent(batteryV);
  246. // static uint32_t t = 0;
  247. // if(t !=TIME_GetTicks()/1000){
  248. // t = TIME_GetTicks()/1000;
  249. // SEGGER_RTT_printf(0,"%d,%d,%d,%d,%d\n",volTemp,batteryV,mIBAT_T.displayvol,mIBAT_T.Displayvol_s,t);
  250. // }
  251. if(mIBAT_T.Displayvol_s != mIBAT_T.vol_filter){
  252. mIBAT_T.Displayvol_s = mIBAT_T.vol_filter;
  253. mIBAT_T.display_t = TIME_GetTicks();
  254. }
  255. displayvol_process(charge_state_c);
  256. // static uint8_t vol_temp =0;
  257. // if(vol_temp != mIBAT_T.displayvol){
  258. // vol_temp =mIBAT_T.displayvol;
  259. // SEGGER_RTT_printf(0,"&&&&&&&&&&>mIBAT_T.vol_filter:%d(%d),tim:%d\n\n\n",batteryV,mIBAT_T.displayvol,TIME_GetTicks()/1000);
  260. // }
  261. }
  262. void Battery_Initialize(void)
  263. {
  264. ADC_SetPinChannel(PIN_ADC_IN, PIN_ADC_CHANNEL);
  265. Process_Start(100,"Battery",Battery_process);
  266. Wakeup_Regist(cb_batteryWakeup);
  267. Sleep_Regist(cb_batterySleep);
  268. }
  269. /**********************************************************
  270. * 函数名字:User_SAADC_DisOrEnable
  271. * 函数作用:SAADC的打开和关闭
  272. * 函数参数:无
  273. * 函数返回值:无
  274. ***********************************************************/
  275. void Battery_Enable(bool value)
  276. {
  277. static bool battery_Open_Flag =false;
  278. int16_t batteryVoltage;
  279. if(value == battery_Open_Flag)return;
  280. if(value){
  281. nrf_gpio_cfg_output(PIN_ADC_EN); nrf_gpio_pin_write(PIN_ADC_EN,0);
  282. for(int i=0;i<filterLen;i++){
  283. MediumFilter(ADC_RESULT_IN_MILLI_VOLTS(ADC_GetValue(PIN_ADC_CHANNEL))*5/3);
  284. }
  285. batteryVoltage = (ADC_RESULT_IN_MILLI_VOLTS(ADC_GetValue(PIN_ADC_CHANNEL))*5/3);
  286. uint32_t charge_state_c = nrf_gpio_pin_read(PIN_CHARGING);
  287. mIBAT_T.vol_value = batteryVoltage;
  288. batteryVoltage = Charging_voltage_calibration(batteryVoltage,0,charge_state_c);
  289. mIBAT_T.vol_filter = Battery_UpdatePersent(batteryVoltage);
  290. mIBAT_T.displayvol = mIBAT_T.vol_filter;
  291. mIBAT_T.Displayvol_s = mIBAT_T.vol_filter;
  292. mIBAT_T.behind_vol = mIBAT_T.vol_filter;
  293. SEGGER_RTT_printf(0,"ADC_Enable,%d,%d,%d\n",batteryVoltage,mIBAT_T.vol_filter,mIBAT_T.displayvol);
  294. }else{
  295. nrf_gpio_cfg_output(PIN_ADC_EN); nrf_gpio_pin_write(PIN_ADC_EN,1);
  296. }
  297. battery_Open_Flag = value;
  298. }