#include "drv_power.h" #include "hrtim.h" #include "FreeRTOS.h" osMutexId mutex_adc; adcInfo_t power_voltage; adcInfo_t buck_in_voltage; adcInfo_t buck_out_voltage; adcInfo_t bat_voltage; adcInfo_t bat_current; adcInfo_t bat_temper; #define ADC_PWR_VOLTAGE ADC_CHANNEL_1 #define ADC_BIN_VOLTAGE ADC_CHANNEL_2 #define ADC_BOU_VOLTAGE ADC_CHANNEL_3 #define ADC_BAT_VOLTAGE ADC_CHANNEL_4 #define ADC_BAT_CURRENT ADC_CHANNEL_6 #define ADC_TEMPERATURE ADC_CHANNEL_9 void adc_init(void) { power_voltage.channel = ADC_PWR_VOLTAGE; power_voltage.filter_buff = (double *)pvPortMalloc(FILTER_BUFF_DEEP * 8); power_voltage.filter_deep = FILTER_BUFF_DEEP; power_voltage.scale = &scale_pwr; buck_in_voltage.channel = ADC_BIN_VOLTAGE; buck_in_voltage.filter_buff = (double *)pvPortMalloc(FILTER_BUFF_DEEP * 8); buck_in_voltage.filter_deep = FILTER_BUFF_DEEP; buck_in_voltage.scale = &scale_buck_in; buck_out_voltage.channel = ADC_BOU_VOLTAGE; buck_out_voltage.filter_buff = (double *)pvPortMalloc(FILTER_BUFF_DEEP * 8); buck_out_voltage.filter_deep = FILTER_BUFF_DEEP; buck_out_voltage.scale = &scale_buck_out; bat_voltage.channel = ADC_BAT_VOLTAGE; bat_voltage.filter_buff = (double *)pvPortMalloc(FILTER_BUFF_DEEP * 8); bat_voltage.filter_deep = FILTER_BUFF_DEEP; bat_voltage.scale = &scale_bat; bat_current.channel = ADC_BAT_CURRENT; bat_current.filter_buff = (double *)pvPortMalloc(FILTER_BUFF_DEEP * 8); bat_current.filter_deep = FILTER_BUFF_DEEP; bat_current.scale = &scale_current; bat_temper.channel = ADC_TEMPERATURE; bat_temper.filter_buff = (double *)pvPortMalloc(FILTER_BUFF_DEEP * 8); bat_temper.filter_deep = FILTER_BUFF_DEEP; bat_temper.scale = &scale_temp; osMutexDef(adc); mutex_adc = osMutexCreate(osMutex(adc)); HAL_ADCEx_Calibration_Start(&hadc1,ADC_SINGLE_ENDED); osDelay(100); } uint32_t adc_value(uint32_t channel) { uint32_t voltage = 0; if(mutex_adc && !osMutexWait(mutex_adc, portMAX_DELAY)) { ADC_MultiModeTypeDef multimode = {0}; ADC_ChannelConfTypeDef sConfig = {0}; //建立结构体 multimode.Mode = ADC_MODE_INDEPENDENT; if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK) { Error_Handler(); } /** Configure Regular Channel */ sConfig.Channel = channel; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_92CYCLES_5; sConfig.SingleDiff = ADC_SINGLE_ENDED; sConfig.OffsetNumber = ADC_OFFSET_NONE; sConfig.Offset = 0; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } HAL_ADC_Start(&hadc1);//开始转换 HAL_ADC_PollForConversion(&hadc1,0xffff);//等待完成 voltage = HAL_ADC_GetValue(&hadc1);//读取转换置 HAL_ADC_Stop(&hadc1);//关闭转换 osMutexRelease(mutex_adc); } return voltage; } double ADC_filterbuff_push_pull(double value,double *buff,uint32_t filter_deep) { //冒泡排序 for (int i = 0; i < filter_deep - 1; i++) { for (int j = 0; j < filter_deep-i-1; j++) { if (buff[j] > buff[j+1]) { // 交换 double temp = buff[j]; buff[j] = buff[j+1]; buff[j+1] = temp; } } } //去掉最大值,最小值,然后取均值,最为最新值放入缓存 int max_index = filter_deep - 1; int min_index = 0; //取均值 double sum = value; for(int i = 1; i < filter_deep - 1; i++) { sum += buff[i]; } sum = sum / (filter_deep - 1); //新的值插入队尾和队头 buff[0] = sum; buff[filter_deep -1] = sum; return sum; } //读取对应的ADC uint32_t vol_value = 0; double get_voltage(adcInfo_t *ptr) { double voltage = -1; //读取电压 uint32_t value = adc_value(ptr->channel); //计算电压 voltage = (value /4096.0) * 3.3; vol_value = value; if(ptr->scale) { voltage = ptr->scale(voltage);//转成对应电压 } voltage = ADC_filterbuff_push_pull(voltage,ptr->filter_buff,ptr->filter_deep); //返回 return voltage; } //电池总电压转换系数 double scale_bat(double value) { double voltage = 0; //计算电压 /* Vi = Vx(R1+R2+R3)/R2; R1 = 300k R2 = 300k R3 = 12k */ voltage = value * (300+300+12)/12.0; return voltage; } //电源总电压转换系数 double scale_pwr(double value) { double voltage = 0; //计算电压 /* Vi = Vx(R1+R2+R3)/R2; R1 = 300k R2 = 300k R3 = 12k */ voltage = value * (300+300+12)/12.0; return voltage; } //buck输入电压转换系数 double scale_buck_in(double value) { double voltage = 0; //计算电压 /* Vi = Vx(R1+R2+R3)/R2; R1 = 300k R2 = 300k R3 = 12k */ voltage = value * (300+300+12)/12.0; return voltage; } //buck输出电压转换系数 double scale_buck_out(double value) { double voltage = 0; //计算电压 /* Vi = Vx(R1+R2+R3)/R2; R1 = 300k R2 = 300k R3 = 12k */ voltage = value * (300+300+12)/12.0; return voltage; } //buck输出电压转换系数 double scale_current(double value) { double voltage = 0; //计算电压 /* Vi = Vx(R1+R2+R3)/R2; R1 = 300k R2 = 300k R3 = 12k */ voltage = value * 0.185; return voltage; } //温度转换系数 #define R0 10000.0 #define T0 298.15 #define B 3435.0 /* Vi = 5.2 R1 = 9.41k R2 = 4.95k Rt = (UxR1+(Ux-U1)R2)/(U1-Ux) */ #define Vi 3.3 #define R1 1000.0 #define R2 1000.0 double scale_temp(double Vx) { double voltage = 0; double Rt = 0; Rt = (Vx*R1 + (Vx - Vi) * R2)/(Vi - Vx ); if(Rt < 0) { Rt = 0; } //计算温度 double temperature_deg = B / (log(Rt/R0) + B/T0) - 273.15; //返回温度 return temperature_deg; return voltage; } //定时器周期 #define HRTIM_PERIOD (54400) void power_init(void) { HAL_HRTIM_WaveformCounterStart(&hhrtim1,HRTIM_TIMERID_TIMER_A); HAL_HRTIM_WaveformOutputStart(&hhrtim1, HRTIM_OUTPUT_TA1); __HAL_HRTIM_SETPERIOD(&hhrtim1, HRTIM_TIMERINDEX_TIMER_A, HRTIM_PERIOD); } void power_set(uint32_t pwm) { if(pwm <= HRTIM_PERIOD) { __HAL_HRTIM_SETCOMPARE(&hhrtim1, HRTIM_TIMERINDEX_TIMER_A , HRTIM_COMPAREUNIT_1, pwm); } else { __HAL_HRTIM_SETCOMPARE(&hhrtim1, HRTIM_TIMERINDEX_TIMER_A , HRTIM_COMPAREUNIT_1, 0); } } uint16_t power_state(void) { return HRTIM1->sTimerxRegs->CMP1xR; }