User_Battery.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /*********************************************************************
  2. *
  3. * 文件名: User_Battery.c
  4. * 功能描述:设备电池电量管理
  5. * 作者: 陈俊超
  6. * 时间:2020-11-20
  7. *
  8. ********************************************************************/
  9. #include "nrf.h"
  10. #include "nrf_drv_saadc.h"
  11. #include "nrf_drv_ppi.h"
  12. #include "nrf_drv_timer.h"
  13. #include "app_timer.h"
  14. #include "User_Battery.h"
  15. /********************** 变量区 **************************************/
  16. static nrf_saadc_value_t m_buffer_Voltage[BatteryVoltageNumber];
  17. static uint16_t Battery_ADC =0;//电池ADC值
  18. #if (PCB_VERSION ==0)
  19. static uint8_t ADC_Channel =5;
  20. #elif (PCB_VERSION ==1)
  21. static uint8_t ADC_Channel =3;
  22. #elif (PCB_VERSION ==2)
  23. static uint8_t ADC_Channel =0;
  24. #elif (PCB_VERSION ==3)
  25. static uint8_t ADC_Channel =3;
  26. #endif
  27. /********************** 函数功能区 **************************************/
  28. /**********************************************************
  29. * 函数名字:bubble_sort
  30. * 函数作用:冒泡排序
  31. * 函数参数:a:需要排列的数组
  32. * n: 数组长度
  33. * 函数返回值:无
  34. ***********************************************************/
  35. void bubble_sort(uint16_t a[], uint16_t n)
  36. {
  37. int i,j;
  38. uint16_t temp;
  39. for (j=0;j<n-1;j++){
  40. for (i=0;i<n-1-j;i++){
  41. if(a[i]>a[i+1]){
  42. temp=a[i];
  43. a[i]=a[i+1];
  44. a[i+1]=temp;
  45. }
  46. }
  47. }
  48. }
  49. int filter(int data)
  50. {
  51. #define filter_len 10
  52. static int buffer[filter_len] = {0};
  53. static int* buffer_p = (int*)buffer + (filter_len - 1);
  54. static int sum = (filter_len >> 1);
  55. sum -= *buffer_p;
  56. *buffer_p-- = data;
  57. sum += data;
  58. if (buffer_p < buffer)
  59. {
  60. buffer_p += filter_len;
  61. }
  62. return sum / filter_len;
  63. }
  64. short filter_mid_averange(short* p)
  65. {
  66. int i;
  67. short buf[filter_mid_averange_number];
  68. for(i=0;i<filter_mid_averange_number;i++){
  69. buf[i] = p[i];
  70. }
  71. bubble_sort(buf,filter_mid_averange_number);
  72. return buf[filter_mid_averange_number>>1];
  73. }
  74. short filter_mid(short val)
  75. {
  76. static short buf[filter_mid_averange_number];
  77. static int dex = 0;
  78. buf[dex] = val;
  79. if(++dex>=filter_mid_averange_number) dex = 0;
  80. return filter_mid_averange(buf);
  81. }
  82. /**********************************************************
  83. * 函数名字:saadc_callback
  84. * 函数作用:adc 事件回调
  85. * 函数参数:p_event:事件类型
  86. * 函数返回值:无
  87. ***********************************************************/
  88. static void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
  89. {
  90. if (p_event->type == NRF_DRV_SAADC_EVT_DONE){
  91. ret_code_t err_code = nrf_drv_saadc_buffer_convert(m_buffer_Voltage, BatteryVoltageNumber);
  92. APP_ERROR_CHECK(err_code);
  93. }
  94. }
  95. /**********************************************************
  96. * 函数名字:saadc_init
  97. * 函数作用:Adc模块功能初始化
  98. * 函数参数:无
  99. * 函数返回值:无
  100. ***********************************************************/
  101. static void saadc_init(void)
  102. {
  103. ret_code_t err_code;
  104. nrf_gpio_cfg_input(PIN_ADC_IN,NRF_GPIO_PIN_NOPULL);//设置ADC引脚为浮空
  105. #if (PCB_VERSION ==0)
  106. nrf_saadc_channel_config_t channel_config =
  107. NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(ADC_Channel+1);
  108. #elif (PCB_VERSION ==1)
  109. nrf_saadc_channel_config_t channel_config =
  110. NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(ADC_Channel+1);
  111. #else
  112. nrf_saadc_channel_config_t channel_config =
  113. NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(ADC_Channel+1);
  114. #endif
  115. //单次阻塞式读取,不需要回调
  116. //err_code = nrf_drv_saadc_init(NULL, saadc_callback);
  117. err_code = nrf_drv_saadc_init(NULL, NULL);
  118. APP_ERROR_CHECK(err_code);
  119. //初始化通道0
  120. err_code = nrf_drv_saadc_channel_init(ADC_Channel, &channel_config);
  121. APP_ERROR_CHECK(err_code);
  122. }
  123. void Quick_GetBatteryPersent(void)
  124. {
  125. for(uint8_t temp =0;temp<filter_mid_averange_number;temp++)
  126. {
  127. GetBatteryVoltage_adc();
  128. nrf_delay_ms(20);
  129. }
  130. }
  131. /**********************************************************
  132. * 函数名字:GetBatteryCurrentPersen
  133. * 函数作用:获取电池电量百分比
  134. * 函数参数:adcvalue :读取到ADC值
  135. * 函数返回值:电量值
  136. ***********************************************************/
  137. uint8_t GetBatteryCurrentPersent()
  138. {
  139. #if 0
  140. const unsigned short list[3][12]={
  141. {100,90,80,70,60,50,40,30,20,10,5,0},
  142. {4200,4060,3980,3870,3820,3790,3770,3740,3680,3450,3000},
  143. {678,651,640,629,621,610,606,603,600,586,548,470}
  144. };
  145. if(Battery_ADC>list[2][0])return 100;
  146. if(Battery_ADC<=list[2][11])return 0;
  147. for(int i=0;i<11;i++)
  148. {
  149. if((Battery_ADC > list[2][i+1]) && (Battery_ADC <= list[2][i]))
  150. {
  151. return (list[0][i]-list[0][i+1])*(Battery_ADC-list[2][i+1])/(list[2][i]-list[2][i+1]) + list[0][i+1];
  152. }
  153. }
  154. #endif
  155. #if 1
  156. const unsigned short list[3][3]={
  157. {100,8,1},
  158. {4000,3300,2960},
  159. {683,565,507}
  160. };
  161. static short adcvalue_old=1000;
  162. short adcvalue_n=Battery_ADC;
  163. #if 1
  164. if((Battery_ADC - adcvalue_old > 0)&&(Battery_ADC - adcvalue_old < 5))adcvalue_n=adcvalue_old;
  165. else adcvalue_old=Battery_ADC;
  166. #endif
  167. if(adcvalue_n>list[2][0])return 100;
  168. if(adcvalue_n<=list[2][2])return 0;
  169. for(int i=0;i<3;i++)
  170. {
  171. if((adcvalue_n > list[2][i+1]) && (adcvalue_n <= list[2][i]))
  172. {
  173. return (list[0][i]-list[0][i+1])*(adcvalue_n-list[2][i+1])/(list[2][i]-list[2][i+1]) + list[0][i+1];
  174. }
  175. }
  176. #endif
  177. return 100;
  178. }
  179. /**********************************************************
  180. * 函数名字:StartBattery_Filter
  181. * 函数作用:获取电池的ADC值,并且使用冒泡排序过滤数据
  182. * 函数参数:无
  183. * 函数返回值:无
  184. ***********************************************************/
  185. void StartBattery_Filter(void)
  186. {
  187. nrf_saadc_value_t Batterysample;
  188. ret_code_t err_code = nrfx_saadc_sample_convert(ADC_Channel, &Batterysample);
  189. Battery_ADC = filter(filter_mid(Batterysample));
  190. #if DEBUG_EN
  191. //NRF_LOG_INFO("sample:%d\n",Battery_ADC*3600/1024);
  192. #endif
  193. }
  194. /**********************************************************
  195. * 函数名字:GetBatteryVoltage
  196. * 函数作用:获取电池的ADC值,并且使用冒泡排序过滤数据
  197. * 函数参数:无
  198. * 函数返回值:无
  199. ***********************************************************/
  200. uint16_t GetBatteryVoltage_adc(void)
  201. {
  202. return Battery_ADC;
  203. }
  204. /**********************************************************
  205. * 函数名字:User_SAADC_DisOrEnable
  206. * 函数作用:SAADC的打开和关闭
  207. * 函数参数:无
  208. * 函数返回值:无
  209. ***********************************************************/
  210. void User_SAADC_DisOrEnable(bool value)
  211. {
  212. static bool Saadc_Open_Flag =false;
  213. uint32_t err_code;
  214. if(value == Saadc_Open_Flag)return;
  215. if(value){
  216. saadc_init();
  217. }
  218. else{
  219. err_code = nrfx_saadc_channel_uninit(ADC_Channel);
  220. nrfx_saadc_uninit();
  221. }
  222. Saadc_Open_Flag = value;
  223. }