hal_battery_HasPowerEnPin.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. /*********************************************************************
  2. * INCLUDES
  3. */
  4. #include "hal_battery.h"
  5. /*********************************************************************
  6. * DEFINITIONS
  7. */
  8. #if BATTERY_CAPACITY ==0
  9. #define BAT_100_P 4100
  10. #define BAT_90_P 4030
  11. #define BAT_80_P 3930
  12. #define BAT_70_P 3880
  13. #define BAT_60_P 3820
  14. #define BAT_50_P 3720
  15. #define BAT_40_P 3650
  16. #define BAT_30_P 3610
  17. #define BAT_20_P 3540
  18. #define BAT_10_P 3450
  19. #define BAT_0_P 3200
  20. #elif BATTERY_CAPACITY ==1
  21. //#define BAT_100_P 4150
  22. //#define BAT_90_P 3980
  23. //#define BAT_80_P 3930
  24. //#define BAT_70_P 3880
  25. //#define BAT_60_P 3830
  26. //#define BAT_50_P 3800
  27. //#define BAT_40_P 3770
  28. //#define BAT_30_P 3740
  29. //#define BAT_20_P 3700
  30. //#define BAT_10_P 3670
  31. //#define BAT_0_P 3200
  32. #define BAT_100_P 4150
  33. #define BAT_90_P 4040
  34. #define BAT_80_P 4000
  35. #define BAT_70_P 3940
  36. #define BAT_60_P 3870
  37. #define BAT_50_P 3840
  38. #define BAT_40_P 3800
  39. #define BAT_30_P 3760
  40. #define BAT_20_P 3720
  41. #define BAT_10_P 3670
  42. #define BAT_0_P 3200
  43. #endif
  44. #define ADC_REF_VOLTAGE_IN_MILLIVOLTS 600 /**< Reference voltage (in milli volts) used by ADC while doing conversion. */
  45. #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.*/
  46. #define ADC_RES_10BIT 4096 /**< Maximum digital value for 10-bit ADC conversion. */
  47. // VP = (RESULT * REFERENCE / 2^10) * 6
  48. #define ADC_RESULT_IN_MILLI_VOLTS(ADC_VALUE)\
  49. ((((ADC_VALUE) * ADC_REF_VOLTAGE_IN_MILLIVOLTS) / ADC_RES_10BIT) * ADC_PRE_SCALING_COMPENSATION)
  50. /*********************************************************************
  51. * LOCAL VARIABLES
  52. */
  53. const int16_t filterLen = 100;
  54. static uint8_t vol = 0;
  55. static uint8_t displayvol = 0,SourceDisplayvol =0 ;
  56. static uint32_t displaytim=0;
  57. static int16_t real_battery =0;
  58. /*********************************************************************
  59. * LOCAL FUNCTIONS
  60. */
  61. static void Bubble_int16(int16_t a[],int16_t m)
  62. {
  63. //冒泡排序
  64. int16_t i,j;
  65. int16_t t;
  66. for(i=0;i<m-1;i++){//n个数的数列总共扫描n-1次
  67. for(j=0;j<m-i-1;j++){//每一趟扫描到a[n-i-2]与a[n-i-1]比较为止结束
  68. if(a[j]>a[j+1]){//后一位数比前一位数小的话,就交换两个数的位置(升序)
  69. t=a[j+1];
  70. a[j+1]=a[j];
  71. a[j]=t;
  72. }
  73. }
  74. }
  75. }
  76. static int16_t MediumFilter(int16_t val)
  77. {
  78. static int16_t filterArr[filterLen];
  79. static int16_t filterDex = 0;
  80. static int16_t res = 0;
  81. filterArr[filterDex] = val;
  82. if(++filterDex>=filterLen){filterDex = 0;
  83. // SEGGER_RTT_printf(0,"filterArr:"); for(int i=0;i<filterLen;i++){SEGGER_RTT_printf(0,"%d,",filterArr[i]);} SEGGER_RTT_printf(0,"\n");
  84. Bubble_int16(filterArr,filterLen);
  85. // SEGGER_RTT_printf(0,"filterArr:"); for(int i=0;i<filterLen;i++){SEGGER_RTT_printf(0,"%d,",filterArr[i]);} SEGGER_RTT_printf(0,"\n");
  86. res = filterArr[filterLen/2];
  87. }
  88. return res;
  89. }
  90. static int16_t Charging_voltage_calibration(int16_t batteryVoltage,uint8_t interval_time_MS){
  91. uint32_t charge_state_c =0;
  92. static uint32_t full_charge_temp = 0;
  93. static uint32_t chargechange = 0;
  94. static uint16_t henyatime = 0;
  95. int16_t bat_cal =0;
  96. static uint8_t behind_vol = 0;
  97. charge_state_c = nrf_gpio_pin_read(PIN_POWER_EN);
  98. if(chargechange != charge_state_c){//插入充电,跳变
  99. chargechange = charge_state_c;
  100. if(charge_state_c){
  101. full_charge_temp =0 ;
  102. #if BATTERY_CAPACITY == 0
  103. if(vol <= 70)henyatime = 60;
  104. else if(vol == 80)henyatime = 140;
  105. else if(vol == 90)henyatime = 162;
  106. else if(vol == 100)henyatime = 0;
  107. #elif BATTERY_CAPACITY == 1
  108. if(vol <= 70)henyatime = 90;
  109. else if(vol == 80)henyatime = 200;
  110. else if(vol == 90)henyatime = 220;
  111. else if(vol == 100)henyatime = 0;
  112. #endif
  113. behind_vol = vol;
  114. SEGGER_RTT_printf(0,"Charging_voltage_calibration %d,%d\n",vol,henyatime);
  115. }
  116. }
  117. if(charge_state_c){
  118. #if BATTERY_CAPACITY == 0
  119. if(batteryVoltage >= 4170){//恒压
  120. #elif BATTERY_CAPACITY == 1
  121. if(batteryVoltage >= 4200){//恒压
  122. #endif
  123. if(full_charge_temp < 0xFFFFFFFF)full_charge_temp += interval_time_MS;
  124. switch(behind_vol){
  125. case 100:
  126. batteryVoltage = BAT_100_P+20;
  127. break;
  128. case 90:
  129. if(full_charge_temp/1000 > henyatime){
  130. full_charge_temp =0;
  131. batteryVoltage = BAT_100_P+20;
  132. behind_vol = 100;
  133. henyatime = 0;
  134. }
  135. else batteryVoltage = BAT_90_P+20;
  136. break;
  137. case 80:
  138. if(full_charge_temp/1000 > henyatime){
  139. behind_vol = 90;
  140. batteryVoltage = BAT_90_P+20;
  141. #if BATTERY_CAPACITY == 0
  142. henyatime = 160;
  143. #elif BATTERY_CAPACITY == 1
  144. henyatime = 220;
  145. #endif
  146. SEGGER_RTT_printf(0,"henya:%d,%d,%d\n",behind_vol,henyatime,full_charge_temp);
  147. full_charge_temp =0;
  148. }
  149. else batteryVoltage = BAT_80_P+20;
  150. break;
  151. case 70:
  152. if(full_charge_temp/1000 > henyatime){
  153. batteryVoltage = BAT_80_P+20;
  154. behind_vol = 80;
  155. #if BATTERY_CAPACITY == 0
  156. henyatime = 140;
  157. #elif BATTERY_CAPACITY == 1
  158. henyatime = 200;
  159. #endif
  160. SEGGER_RTT_printf(0,"henya:%d,%d,%d\n",behind_vol,henyatime,full_charge_temp);
  161. full_charge_temp =0;
  162. }
  163. else batteryVoltage = BAT_70_P+20;
  164. break;
  165. default:
  166. if(full_charge_temp/1000 > henyatime){
  167. batteryVoltage = BAT_70_P+20;
  168. behind_vol = 70;
  169. #if BATTERY_CAPACITY == 0
  170. henyatime = 60;
  171. #elif BATTERY_CAPACITY == 1
  172. henyatime = 90;
  173. #endif
  174. SEGGER_RTT_printf(0,"henya:%d,%d,%d\n",behind_vol,henyatime,full_charge_temp);
  175. full_charge_temp =0;
  176. }
  177. else batteryVoltage = BAT_60_P+20;
  178. break;
  179. }
  180. }else{//恒流
  181. full_charge_temp =0;
  182. #if BATTERY_CAPACITY == 0
  183. if(batteryVoltage >= 3810)batteryVoltage -= 320;
  184. else if(batteryVoltage < 3810 && batteryVoltage >= BAT_0_P)batteryVoltage -= 400;
  185. #elif BATTERY_CAPACITY == 1
  186. if(batteryVoltage >= 3900)batteryVoltage -= 310;
  187. else if(batteryVoltage >= BAT_0_P)batteryVoltage -= 400;
  188. #endif
  189. else if(batteryVoltage < BAT_0_P)batteryVoltage = BAT_0_P;
  190. }
  191. }
  192. else full_charge_temp =0;
  193. bat_cal = batteryVoltage;
  194. return bat_cal;
  195. }
  196. static uint8_t GetBatteryPersent(int16_t batteryVoltage)
  197. {
  198. uint8_t vol_t = 0;
  199. if(batteryVoltage >= BAT_100_P)vol_t = 100;
  200. else if(batteryVoltage >= BAT_90_P)vol_t = 90;
  201. else if(batteryVoltage >= BAT_80_P)vol_t = 80;
  202. else if(batteryVoltage >= BAT_70_P)vol_t = 70;
  203. else if(batteryVoltage >= BAT_60_P)vol_t = 60;
  204. else if(batteryVoltage >= BAT_50_P)vol_t = 50;
  205. else if(batteryVoltage >= BAT_40_P)vol_t = 40;
  206. else if(batteryVoltage >= BAT_30_P)vol_t = 30;
  207. else if(batteryVoltage >= BAT_20_P)vol_t = 20;
  208. else if(batteryVoltage >= BAT_10_P)vol_t = 10;
  209. else if(batteryVoltage < BAT_10_P && batteryVoltage >= BAT_0_P)vol_t = ((batteryVoltage-BAT_0_P)/((BAT_10_P - BAT_0_P)/10));
  210. else if(batteryVoltage < BAT_0_P)vol_t = 0;
  211. return vol_t;
  212. }
  213. static void cb_batteryWakeup(uint32_t t)
  214. {
  215. nrf_gpio_cfg_output(PIN_ADC_EN); nrf_gpio_pin_write(PIN_ADC_EN,0);
  216. }
  217. static void cb_batterySleep(uint32_t t)
  218. {
  219. nrf_gpio_cfg_output(PIN_ADC_EN); nrf_gpio_pin_write(PIN_ADC_EN,1);
  220. }
  221. /*********************************************************************
  222. * PUBLIC FUNCTIONS
  223. */
  224. int16_t ADC_GetValue(uint32_t channel)
  225. {
  226. int16_t temp=0;
  227. ADC_Read(channel, &temp);
  228. return temp;
  229. }
  230. /**********************************************************
  231. * 函数名字:GetBatteryCurrentPersen
  232. * 函数作用:获取电池电量百分比
  233. * 函数参数:adcvalue :读取到ADC值
  234. * 函数返回值:电量值
  235. ***********************************************************/
  236. uint8_t Battery_GetBatteryPersent(void)
  237. {
  238. return displayvol;
  239. }
  240. void displayvol_process(void){
  241. uint32_t charge_state_c =0;
  242. charge_state_c = nrf_gpio_pin_read(PIN_POWER_EN);
  243. if(charge_state_c){
  244. if(SourceDisplayvol > displayvol){
  245. if(displayvol >=10 && displayvol < 100){
  246. if(TIME_GetTicks()-displaytim >= 2000){
  247. displaytim = TIME_GetTicks();
  248. displayvol+=1;
  249. SEGGER_RTT_printf(0,"1 displayvol_process:%d,%d,%d\n",SourceDisplayvol,displayvol,vol);
  250. }
  251. }
  252. else if(displayvol < 10){
  253. if(TIME_GetTicks()-displaytim >= 2000){
  254. displaytim = TIME_GetTicks();
  255. displayvol+=1;
  256. SEGGER_RTT_printf(0,"2 displayvol_process:%d,%d,%d\n",SourceDisplayvol,displayvol,vol);
  257. }
  258. }
  259. }
  260. }
  261. else{
  262. if(SourceDisplayvol < displayvol){
  263. if(TIME_GetTicks()-displaytim >= 60000){ displaytim = TIME_GetTicks();
  264. if(displayvol > 10 && displayvol <= 100)displayvol -= 10;
  265. else if(displayvol <= 10 && displayvol >0)displayvol -=1;
  266. SEGGER_RTT_printf(0,"3 displayvol_process:%d,%d,%d\n",SourceDisplayvol,displayvol,vol);
  267. }
  268. }
  269. }
  270. }
  271. uint8_t Battery_BatteryIs_0(void)
  272. {
  273. if(real_battery <= BAT_0_P)return 1;
  274. else return 0;
  275. }
  276. void battery_process(void)
  277. {
  278. static uint32_t tim=0;
  279. static uint32_t tim_charge=100;
  280. int16_t batteryVoltage;
  281. int16_t adcVal;
  282. int16_t volTemp;
  283. displayvol_process();
  284. if(TIME_GetTicks()-tim >= tim_charge){ tim = TIME_GetTicks();
  285. if( nrf_gpio_pin_read(PIN_POWER_EN)) tim_charge = 10;
  286. else tim_charge = 100;
  287. adcVal = ADC_GetValue(PIN_ADC_CHANNEL);
  288. volTemp = ADC_RESULT_IN_MILLI_VOLTS(adcVal)*5/3; // 电池电压转换计算
  289. batteryVoltage = MediumFilter(volTemp);
  290. real_battery = batteryVoltage;
  291. batteryVoltage = Charging_voltage_calibration(batteryVoltage,tim_charge);
  292. static uint32_t t = 0;
  293. if(t != TIME_GetTicks()/1000){
  294. t = TIME_GetTicks()/1000;
  295. SEGGER_RTT_printf(0,"%d,%d,%d,%d,%d\n",adcVal,volTemp,batteryVoltage,displayvol,t);
  296. }
  297. vol = GetBatteryPersent(batteryVoltage);
  298. if(SourceDisplayvol != vol){
  299. SourceDisplayvol = vol;
  300. displaytim = TIME_GetTicks();
  301. }
  302. static uint8_t vol_temp =0;
  303. if(vol_temp != displayvol){
  304. vol_temp =displayvol;
  305. SEGGER_RTT_printf(0,"&&&&&&&&&&>vol:%d(%d),tim:%d\n\n\n",batteryVoltage,displayvol,TIME_GetTicks()/1000);
  306. }
  307. }
  308. }
  309. void Battery_Initialize(void)
  310. {
  311. ADC_SetPinChannel(PIN_ADC_IN, PIN_ADC_CHANNEL);
  312. Process_Start(0,battery_process);
  313. Wakeup_Regist(cb_batteryWakeup);
  314. Sleep_Regist(cb_batterySleep);
  315. }
  316. /**********************************************************
  317. * 函数名字:User_SAADC_DisOrEnable
  318. * 函数作用:SAADC的打开和关闭
  319. * 函数参数:无
  320. * 函数返回值:无
  321. ***********************************************************/
  322. void Battery_Enable(bool value)
  323. {
  324. static bool battery_Open_Flag =false;
  325. int16_t batteryVoltage;
  326. if(value == battery_Open_Flag)return;
  327. if(value){
  328. nrf_gpio_cfg_output(PIN_ADC_EN); nrf_gpio_pin_write(PIN_ADC_EN,0);
  329. for(int i=0;i<filterLen;i++){
  330. MediumFilter(ADC_RESULT_IN_MILLI_VOLTS(ADC_GetValue(PIN_ADC_CHANNEL))*5/3);
  331. }
  332. batteryVoltage = (ADC_RESULT_IN_MILLI_VOLTS(ADC_GetValue(PIN_ADC_CHANNEL))*5/3);
  333. batteryVoltage = Charging_voltage_calibration(batteryVoltage,0);
  334. vol = GetBatteryPersent(batteryVoltage);
  335. displayvol = vol;
  336. SourceDisplayvol = vol;
  337. SEGGER_RTT_printf(0,"Battery_Enable,%d,%d,%d\n",batteryVoltage,vol,displayvol);
  338. }else{
  339. nrf_gpio_cfg_output(PIN_ADC_EN); nrf_gpio_pin_write(PIN_ADC_EN,1);
  340. }
  341. battery_Open_Flag = value;
  342. }