/********************************************************************* * * 文件名: User_Battery.c * 功能描述:设备电池电量管理 * 作者: 陈俊超 * 时间:2020-11-20 * ********************************************************************/ #include "nrf.h" #include "nrf_drv_saadc.h" #include "nrf_drv_ppi.h" #include "nrf_drv_timer.h" #include "app_timer.h" #include "User_Battery.h" /********************** 变量区 **************************************/ static nrf_saadc_value_t m_buffer_Voltage[BatteryVoltageNumber]; static uint16_t Battery_ADC =0;//电池ADC值 #if (PCB_VERSION ==0) static uint8_t ADC_Channel =5; #elif (PCB_VERSION ==1) static uint8_t ADC_Channel =3; #elif (PCB_VERSION ==2) static uint8_t ADC_Channel =0; #elif (PCB_VERSION ==3) static uint8_t ADC_Channel =3; #endif /********************** 函数功能区 **************************************/ /********************************************************** * 函数名字:bubble_sort * 函数作用:冒泡排序 * 函数参数:a:需要排列的数组 * n: 数组长度 * 函数返回值:无 ***********************************************************/ void bubble_sort(uint16_t a[], uint16_t n) { int i,j; uint16_t temp; for (j=0;ja[i+1]){ temp=a[i]; a[i]=a[i+1]; a[i+1]=temp; } } } } int filter(int data) { #define filter_len 10 static int buffer[filter_len] = {0}; static int* buffer_p = (int*)buffer + (filter_len - 1); static int sum = (filter_len >> 1); sum -= *buffer_p; *buffer_p-- = data; sum += data; if (buffer_p < buffer) { buffer_p += filter_len; } return sum / filter_len; } short filter_mid_averange(short* p) { int i; short buf[filter_mid_averange_number]; for(i=0;i>1]; } short filter_mid(short val) { static short buf[filter_mid_averange_number]; static int dex = 0; buf[dex] = val; if(++dex>=filter_mid_averange_number) dex = 0; return filter_mid_averange(buf); } /********************************************************** * 函数名字:saadc_callback * 函数作用:adc 事件回调 * 函数参数:p_event:事件类型 * 函数返回值:无 ***********************************************************/ static void saadc_callback(nrf_drv_saadc_evt_t const * p_event) { if (p_event->type == NRF_DRV_SAADC_EVT_DONE){ ret_code_t err_code = nrf_drv_saadc_buffer_convert(m_buffer_Voltage, BatteryVoltageNumber); APP_ERROR_CHECK(err_code); } } /********************************************************** * 函数名字:saadc_init * 函数作用:Adc模块功能初始化 * 函数参数:无 * 函数返回值:无 ***********************************************************/ static void saadc_init(void) { ret_code_t err_code; nrf_gpio_cfg_input(PIN_ADC_IN,NRF_GPIO_PIN_NOPULL);//设置ADC引脚为浮空 #if (PCB_VERSION ==0) nrf_saadc_channel_config_t channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(ADC_Channel+1); #elif (PCB_VERSION ==1) nrf_saadc_channel_config_t channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(ADC_Channel+1); #else nrf_saadc_channel_config_t channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(ADC_Channel+1); #endif //单次阻塞式读取,不需要回调 //err_code = nrf_drv_saadc_init(NULL, saadc_callback); err_code = nrf_drv_saadc_init(NULL, NULL); APP_ERROR_CHECK(err_code); //初始化通道0 err_code = nrf_drv_saadc_channel_init(ADC_Channel, &channel_config); APP_ERROR_CHECK(err_code); } void Quick_GetBatteryPersent(void) { for(uint8_t temp =0;templist[2][0])return 100; if(Battery_ADC<=list[2][11])return 0; for(int i=0;i<11;i++) { if((Battery_ADC > list[2][i+1]) && (Battery_ADC <= list[2][i])) { 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]; } } #endif #if 1 const unsigned short list[3][3]={ {100,8,1}, {4000,3300,2960}, {683,565,507} }; static short adcvalue_old=1000; short adcvalue_n=Battery_ADC; #if 1 if((Battery_ADC - adcvalue_old > 0)&&(Battery_ADC - adcvalue_old < 5))adcvalue_n=adcvalue_old; else adcvalue_old=Battery_ADC; #endif if(adcvalue_n>list[2][0])return 100; if(adcvalue_n<=list[2][2])return 0; for(int i=0;i<3;i++) { if((adcvalue_n > list[2][i+1]) && (adcvalue_n <= list[2][i])) { 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]; } } #endif return 100; } /********************************************************** * 函数名字:StartBattery_Filter * 函数作用:获取电池的ADC值,并且使用冒泡排序过滤数据 * 函数参数:无 * 函数返回值:无 ***********************************************************/ void StartBattery_Filter(void) { nrf_saadc_value_t Batterysample; ret_code_t err_code = nrfx_saadc_sample_convert(ADC_Channel, &Batterysample); Battery_ADC = filter(filter_mid(Batterysample)); #if DEBUG_EN //NRF_LOG_INFO("sample:%d\n",Battery_ADC*3600/1024); #endif } /********************************************************** * 函数名字:GetBatteryVoltage * 函数作用:获取电池的ADC值,并且使用冒泡排序过滤数据 * 函数参数:无 * 函数返回值:无 ***********************************************************/ uint16_t GetBatteryVoltage_adc(void) { return Battery_ADC; } /********************************************************** * 函数名字:User_SAADC_DisOrEnable * 函数作用:SAADC的打开和关闭 * 函数参数:无 * 函数返回值:无 ***********************************************************/ void User_SAADC_DisOrEnable(bool value) { static bool Saadc_Open_Flag =false; uint32_t err_code; if(value == Saadc_Open_Flag)return; if(value){ saadc_init(); } else{ err_code = nrfx_saadc_channel_uninit(ADC_Channel); nrfx_saadc_uninit(); } Saadc_Open_Flag = value; }