Files
checker_slave/source/elec_det/hardware/power.c

537 lines
13 KiB
C
Raw Normal View History

#include "power.h"
#include "base/utility.h"
#include "gpio_cfg.h"
#include "base/delay.h"
#define PowerCurr_AD_BUF_LEN 40
#define POWER_SET_COUNT 20
static volatile CurrentSample_Range_eu latest_range = Current_Max;
static volatile PowerInfo_st def_power_st;
//static uint16_t PowerCurr_AD_buf[PowerCurr_AD_BUF_LEN];
static volatile float f_cur_k;
static volatile float f_cur_b;
static volatile uint8_t uc_power_cal_flag = 0;
volatile PowerInfo_st powerinfo_arrayst[POWER_SET_COUNT] ;
/*
@brief 1.2V电压对应的AD
*/
uint32_t Power_GetBaseVAD()
{
// y1 = kx1+b y2=kx2+b y1-y2/x1-x2
// uint16_t adv_buf[10];
// uint32_t temp_v;
// GetADC0_Value(ADC_CHANNEL_17,adv_buf,10) ;
// Bubble_Sort_u16(adv_buf,10);
// return (adv_buf[4]+adv_buf[5]+adv_buf[6]+adv_buf[7])>>2;
return (uint32_t)(1.2f/3.3f*4096);
}
void Power_CurCalibration()
{
uint16_t adv_buf[10],adv2v5,adv1v25;
uc_power_cal_flag = 1;
GetADC1_Value(VCC_2V5_CH,adv_buf,10) ;
Bubble_Sort_u16(adv_buf,10);
adv2v5 = (adv_buf[4]+adv_buf[5]+adv_buf[6]+adv_buf[7])>>2;
GetADC1_Value(VCC_1V25_CH,adv_buf,10) ;
Bubble_Sort_u16(adv_buf,10);
adv1v25 = (adv_buf[4]+adv_buf[5]+adv_buf[6]+adv_buf[7])>>2;
f_cur_k = 1.245f/((adv2v5 - adv1v25)+1);
f_cur_b = 2.49f-f_cur_k*adv2v5;
// GetADC0_Value(VCC_1V25_CH,adv_buf,10) ;
// Bubble_Sort_u16(adv_buf,10);
// adv1v25 = (adv_buf[4]+adv_buf[5]+adv_buf[6]+adv_buf[7])>>2;
//
// f_cur_k = 1.25f/((adv2v5 - adv1v25)+1);
// f_cur_b = 2.5f-f_cur_k*adv2v5;
}
/*
@brief ADC值转换为电压值
@param1 ul_adv AD原始值
@rtv AD采集到的电压值 1000000
*/
uint32_t Power_ADVGetCalVal_106(uint16_t ul_adv)
{
if(uc_power_cal_flag == 0)
{
Power_CurCalibration();
}
return (uint32_t)((f_cur_k*ul_adv+f_cur_b)*1000000);
}
/*
@brief
*/
uint32_t Power_GetHPowerV()
{
uint32_t adv;
uint16_t adv_buf[10];
Power_CurCalibration();
GetADC1_Value(V_LA_H_CH,adv_buf,10) ;
Bubble_Sort_u16(adv_buf,10);
adv = (adv_buf[4]+adv_buf[5]+adv_buf[6]+adv_buf[7])>>2;
adv = Power_ADVGetCalVal_106(adv);
adv = adv*V_PARAM_1/100000;
return adv;
}
/*
@brief 线
*/
uint32_t Power_GetBousV()
{
uint32_t abus_v,bbus_v;
uint16_t adv_buf[10];
uint32_t hbus_v=0;
Power_CurCalibration();
GetADC1_Value(AD_OUTA_CH,adv_buf,10) ;
Bubble_Sort_u16(adv_buf,10);
abus_v = (adv_buf[4]+adv_buf[5]+adv_buf[6]+adv_buf[7])>>2;
GetADC1_Value(AD_OUTB_CH,adv_buf,10) ;
Bubble_Sort_u16(adv_buf,10);
bbus_v = (adv_buf[4]+adv_buf[5]+adv_buf[6]+adv_buf[7])>>2;
if(bbus_v > abus_v)
{
abus_v = bbus_v;
}
abus_v = Power_ADVGetCalVal_106(abus_v);
abus_v = abus_v*11/100000;
// hbus_v=Power_GetHPowerV();
//? 验证电压失调
// 电压相差过大的时候输出一个离谱的值
// if((hbus_v>abus_v+10)||(abus_v>hbus_v+10)){
// abus_v=500;
// }
return abus_v;
}
/*
@brief
*/
uint32_t Power_GetMPowerV()
{
int32_t adv;
uint16_t adv_buf[10];
GetADC1_Value(V_LA_M_CH,adv_buf,10) ;
Bubble_Sort_u16(adv_buf,10);
adv = (adv_buf[4]+adv_buf[5]+adv_buf[6]+adv_buf[7])>>2;
adv = Power_ADVGetCalVal_106(adv);
adv = adv*V_PARAM_1/100000;
return adv;
}
/*
typedef enum{
R510_0uA_32uA_UC = (uint8_t)0,//x201
R510_0uA_580uA_MC = (uint8_t)1,//x11
R100_0uA_160uA_UC = (uint8_t)2,//x201
R100_0p2mA_3mA_MC = (uint8_t)3,//x11
R10_0p1mA_1p6mA_UC = (uint8_t)4,//x201
R10_2mA_30mA_MC = (uint8_t)5,//x11
Current_Max = (uint8_t)6,
Current_SampleR_OFF = (uint8_t)9,
} CurrentSample_Range_eu;
*/
/*
@brief adc
@param adv adc
@param rang
@rtv uint32_t 0.1uA
*/
uint32_t Power_ConvCur(uint16_t adv,CurrentSample_Range_eu range)
{
uint32_t ul_R,ul_Mut;
uint32_t ul_adv = Power_ADVGetCalVal_106(adv);
switch(range)
{
case R510_0uA_32uA_UC: ul_R = 510; ul_Mut = 201 ; break;
case R510_0uA_580uA_MC: ul_R = 510; ul_Mut = 11; break;
case R100_0uA_160uA_UC: ul_R = 100; ul_Mut = 201; break;
case R100_0p2mA_3mA_MC: ul_R = 100; ul_Mut = 11; break;
case R10_0p1mA_1p6mA_UC: ul_R = 10; ul_Mut = 201; break;
case R10_2mA_30mA_MC: ul_R = 10; ul_Mut = 11; break;
case Current_Max: ul_R = 10; ul_Mut = 1; break;
case Current_SampleR_OFF: ul_R = 510; ul_Mut = 1;break;
default: ul_R = 510; ul_Mut = 1;break;
}
ul_adv = (ul_adv*100 / ul_R /ul_Mut+4)/10;
return ul_adv;
}
//根据电流大小的范围,设置采样电阻
CurrentSample_Range_eu Power_SetSampleCurrentRange(CurrentSample_Range_eu range)
{
switch(range)
{
case R510_0uA_32uA_UC: R510_SW_ON; R100_SW_OFF; R10_SW_OFF; break;
case R510_0uA_580uA_MC: R510_SW_ON; R100_SW_OFF; R10_SW_OFF; break;
case R100_0uA_160uA_UC: R100_SW_ON; R510_SW_OFF; R10_SW_OFF; break;
case R100_0p2mA_3mA_MC: R100_SW_ON; R510_SW_OFF; R10_SW_OFF; break;
case R10_0p1mA_1p6mA_UC: R10_SW_ON; R510_SW_OFF; R100_SW_OFF; break;
case R10_2mA_30mA_MC: R10_SW_ON; R510_SW_OFF; R100_SW_OFF; break;
case Current_Max: R510_SW_ON; R100_SW_ON; R10_SW_ON;break;
case Current_SampleR_OFF: R510_SW_OFF;R100_SW_OFF; R10_SW_OFF;break;
default: range = Current_Max; R510_SW_ON; R100_SW_ON; R10_SW_ON;break;
}
latest_range = range;
return latest_range;
}
/*
@brief AD采样配置
*/
CurrentSample_Range_eu Power_SetSampleRange_Seep(CurrentSample_Range_eu range , uint32_t speed)
{
switch(range)
{
case R510_0uA_32uA_UC: ADC_CurChnnelSet(AN_UA_CH,speed); break;
case R510_0uA_580uA_MC: ADC_CurChnnelSet(AN_MAL_CH,speed); break;
case R100_0uA_160uA_UC: ADC_CurChnnelSet(AN_UA_CH,speed); break;
case R100_0p2mA_3mA_MC: ADC_CurChnnelSet(AN_MAL_CH,speed); break;
case R10_0p1mA_1p6mA_UC: ADC_CurChnnelSet(AN_UA_CH,speed); break;
case R10_2mA_30mA_MC: ADC_CurChnnelSet(AN_MAL_CH,speed); break;
case Current_Max: ADC_CurChnnelSet(AN_MAL_CH,speed); break;
case Current_SampleR_OFF: ADC_CurChnnelSet(AN_MAL_CH,speed);break;
default: ADC_CurChnnelSet(AN_MAL_CH,speed);break;
}
return Power_SetSampleCurrentRange(range);
}
//获取总线电流
uint32_t Power_GetCurrent(void)
{
uint32_t adv;
uint32_t count;
CurrentSample_Range_eu range = latest_range;//档位保存
CurrentSample_Range_eu set_range;
uint32_t adv_base = Power_GetBaseVAD();
if(adv_base < 500)
return 0;
set_range = Power_SetSampleCurrentRange(R10_2mA_30mA_MC);
StartADC2Channel(AN_MAL_CH,ADC_SPEED_SLOW);
delay_us(300);
GetADC_Fast(ADC_CURR_DE);
adv = 0;
for(count = 0; count < 4; count++)
{
adv += GetADC_Fast(ADC_CURR_DE);
}
adv >>= 2;
if(adv > 250){
adv = Power_ConvCur(adv,set_range);//0.1uA
adv = (adv+4)/10;
Power_SetSampleCurrentRange(range);
return adv;
}
set_range = Power_SetSampleCurrentRange(R100_0p2mA_3mA_MC);
StartADC2Channel(AN_MAL_CH,ADC_SPEED_SLOW);
delay_us(300);
GetADC_Fast(ADC_CURR_DE);
adv = 0;
for(count = 0; count < 4; count++)
{
adv += GetADC_Fast(ADC_CURR_DE);
}
adv >>= 2;
if(adv > 250){
adv = Power_ConvCur(adv,set_range);//0.1uA
adv = (adv+4)/10;
Power_SetSampleCurrentRange(range);
return adv;
}
set_range = Power_SetSampleCurrentRange(R10_0p1mA_1p6mA_UC);
StartADC2Channel(AN_UA_CH,ADC_SPEED_SLOW);
delay_ms(2);
GetADC_Fast(ADC_CURR_DE);
adv = 0;
for(count = 0; count < 4; count++)
{
adv += GetADC_Fast(ADC_CURR_DE);
}
adv >>= 2;
if(adv > 250){
adv = Power_ConvCur(adv,set_range);//0.1uA
adv = (adv+4)/10;
Power_SetSampleCurrentRange(range);
return adv;
}
set_range = Power_SetSampleCurrentRange(R100_0uA_160uA_UC);
StartADC2Channel(AN_UA_CH,ADC_SPEED_SLOW);
delay_ms(3);
GetADC_Fast(ADC_CURR_DE);
adv = 0;
for(count = 0; count < 8; count++)
{
adv += GetADC_Fast(ADC_CURR_DE);
}
adv >>= 3;
adv = Power_ConvCur(adv,set_range);//0.1uA
adv = (adv+4)/10;
Power_SetSampleCurrentRange(range);
return adv;
}
/*
@brief 线
@rtv 0
*/
uint8_t PowerCalPrapare(void)
{
//YM硬件直接由公式计算
return 0;
}
//防止突然上电,导致电源崩溃
static void PowerUpFilter(uint16_t tag_dac)
{
uint16_t us_lastdac_h = DAC_GetDataOutputValue(DAC_Channel_1);
if(us_lastdac_h > (tag_dac + 200))
{
while(us_lastdac_h > tag_dac)
{
if((tag_dac + 100) < us_lastdac_h)
{
us_lastdac_h -= 50;
C_H_DAC_Set(us_lastdac_h);
}else{
us_lastdac_h = tag_dac;
C_H_DAC_Set(us_lastdac_h);
}
delay_ms(10);
}
}
}
//电压调节的关系为线性函数
void PowerCalibration(PowerInfo_st* info_st)
{
float vlp,vlm,v_adc_h,v_adc_m;
uint16_t us_basedac_h,us_basedac_m;
uint16_t us_lastdac_h,us_lastdac_m;
uint16_t us_powderv;
uint16_t us_timeout ;
uint32_t diff=0;
uint16_t ok_flg = 0;
uint8_t uc_down_up_flag = 0;
if(info_st->V_LAH < info_st->V_LAM )
{
info_st->V_LAH_DAC = 0;
info_st->V_LAM_DAC = 0;
return ;
}
PAout(LAVC_M_Pin_Nu)=0;PBout(OUTAH_Pin_Nu)=0;
PBout(OUTBL_Pin_Nu)=0;PBout(OUTAL_Pin_Nu)=0;
PCout(POWER_ON_Pin_Nu) = 1;
vlp = info_st->V_LAH;
vlp /= 10;
//(VLP-1.229V)/178K + (VDAC-1.229V)/20K = 0.1229mA
v_adc_h =( 0.1229- (vlp-1.229)/V_PARAM_2)*20+1.229;
us_timeout = 80;
info_st->V_LAH_DAC = 0;
us_basedac_h = (uint16_t)( v_adc_h/3.3 * 4096);
PowerUpFilter(us_basedac_h);
us_lastdac_h = 0;
//us_basedac_h = 250;
ok_flg = 0;
uc_down_up_flag = 0;
while(us_timeout > 0)
{
us_timeout--;
C_H_DAC_Set(us_basedac_h);
us_lastdac_h = us_basedac_h;
switch(uc_down_up_flag)
{
case 0:delay_os_ms(100);break;//首次调压
case 1:delay_os_ms(50);break;//降压
case 2:delay_os_ms(10);break;//升压
}
us_powderv = Power_GetHPowerV();
diff = us_powderv > info_st->V_LAH?us_powderv-info_st->V_LAH:info_st->V_LAH-us_powderv;
if(diff < 2)
{
ok_flg++;
if(ok_flg > 2)
{
info_st->V_LAH_DAC = us_basedac_h;
break;
}else{
continue;
}
}
diff = diff *2;
ok_flg = 0;
if( us_powderv > info_st->V_LAH)
{
us_basedac_h += diff;
uc_down_up_flag = 1;
}else{
us_basedac_h -= diff;
uc_down_up_flag = 2;
}
if(us_basedac_h < 20)
us_basedac_h = 20;
if(us_basedac_h > 4050)
us_basedac_h = 4050;
}
if(info_st->V_LAH_DAC == 0)
return;
//(VM-2.5V)/20k+(VDAC-2.5V)/4.7K = 0.25mA
us_timeout = 100;
info_st->V_LAM_DAC = 0;
vlm = info_st->V_LAM ;
vlm /= 10;
v_adc_m =( 0.25- (vlm-2.5)/20)*4.7+2.5;
us_basedac_m = (uint16_t)(v_adc_m / 3.3 * 4096);
//us_lastdac_m = 250;
ok_flg = 0;
uc_down_up_flag = 0;
while( us_timeout > 0)
{
us_timeout--;
C_M_DAC_Set(us_basedac_m);
us_lastdac_m = us_basedac_m;
switch(uc_down_up_flag)
{
case 0:delay_os_ms(50);break;//首次调压
case 1:delay_os_ms(40);break;//降压
case 2:delay_os_ms(30);break;//升压
default:delay_os_ms(50);break;
}
us_powderv = Power_GetMPowerV();
diff = us_powderv > info_st->V_LAM?us_powderv-info_st->V_LAM:info_st->V_LAM-us_powderv;
if(diff < 2)
{
ok_flg++;
if(ok_flg > 2)
{
info_st->V_LAM_DAC = us_basedac_m;
break;
}
else{
continue;
}
}
ok_flg = 0;
diff = diff *10;
if( us_powderv > info_st->V_LAM)
{
us_basedac_m += diff;
uc_down_up_flag = 1;
}else{
uc_down_up_flag = 2;
us_basedac_m -= diff;
}
if(us_basedac_m < 100)
us_basedac_m = 100;
if(us_basedac_m > 4050)
us_basedac_m = 4050;
}
}
//设置总线电压
void PowerSetVoltage(PowerInfo_st* info_st)
{
memcpy((void *)&def_power_st,info_st,sizeof(PowerInfo_st));
PowerUpFilter(info_st->V_LAH_DAC);
C_H_DAC_Set(info_st->V_LAH_DAC);
C_M_DAC_Set(info_st->V_LAM_DAC);
POWER_ON;
//? 验证电压失调
// delay_ms(5);
// C_H_DAC_Set(info_st->V_LAH_DAC);
// C_M_DAC_Set(info_st->V_LAM_DAC);
}
//获取当前电压配置值
void PowerGetSet(PowerInfo_st* info_st)
{
uint16_t h_dac = DAC_GetDataOutputValue(DAC_Channel_1);
uint16_t m_dac = DAC_GetDataOutputValue(DAC_Channel_2);
info_st->V_LAH = 0;
info_st->V_LAH_DAC = h_dac;
if(h_dac == def_power_st.V_LAH_DAC)
{
info_st->V_LAH = def_power_st.V_LAH;
}
info_st->V_LAM = 0;
info_st->V_LAM_DAC = h_dac;
if(m_dac == def_power_st.V_LAM_DAC)
{
info_st->V_LAM_DAC = m_dac;
}
}
/*
@brief 线
@param h_v/10
@param m_v/10
@rtv 0 1
*/
uint8_t PowerCalibration_set(uint16_t h_v,uint16_t m_v)
{
uint32_t ul_index = 0;
PowerInfo_st powerinfo_st;
rt_memset(&powerinfo_st,0,sizeof(PowerInfo_st));
while(ul_index < POWER_SET_COUNT)
{
//if( powerinfo_arrayst[ul_index].V_LAH == h_v && powerinfo_arrayst[ul_index].V_LAM == m_v)
if( powerinfo_arrayst[ul_index].V_LAH == h_v)
{
break;
}
ul_index++;
}
//在现有电压列表中能够查询到校准后的电压
if(ul_index < POWER_SET_COUNT)
{
memcpy((void *)&powerinfo_st,(void *)&powerinfo_arrayst[ul_index],sizeof(PowerInfo_st));
PowerSetVoltage(&powerinfo_st);
return 0;
}
powerinfo_st.V_LAH = h_v;
powerinfo_st.V_LAM = m_v;
PowerCalibration(&powerinfo_st);
if(powerinfo_st.V_LAH_DAC == 0 || powerinfo_st.V_LAM_DAC == 0)
{
LED1_Out = 1;
return 1;
}
//校准完成后,设置总线电压
PowerSetVoltage(&powerinfo_st);
//查找为使用的配置缓存,将新设置的电压保存
ul_index = 0;
while(ul_index < POWER_SET_COUNT)
{
if( powerinfo_arrayst[ul_index].V_LAH_DAC == 0 || powerinfo_arrayst[ul_index].V_LAM_DAC == 0)
{
memcpy((void *)&powerinfo_arrayst[ul_index],&powerinfo_st,sizeof(PowerInfo_st));
break;
}
ul_index++;
}
return 0;
}