Files
B_Current_Ctrl/BSP/drv_power.c
T
2025-08-29 11:31:13 +08:00

337 lines
6.1 KiB
C

#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;
}