337 lines
6.1 KiB
C
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;
|
|
}
|
|
|
|
|
|
|