低压降频的处理逻辑
1:ADC判断临界物理值是否达到---多次检测滤波->设定状态
2:进入状态后进行阶梯递减或者差值递减,使用一个系数作为PWM的阶梯值接口
3:计算出降额系数,应用到PWM
设一灯板小于7.5V进入低压保护灭灯,大于8.5V退出保护重新亮灯
大于19V进行过压保护灭灯
检测电压低于10V,持续时间大于1000ms开始进行电压降额,100ms调整一次,每次不超过3%
需要注意
1:灯亮时会分压,实际的阀值电压可能需要实测调整
2:万一灯碰到临界值后开始降额后,电流下降,检测电压上升,恢复到临界值以上,是否会导致暗--亮--暗持续闪烁,可以考虑加入类似噪声桶的区间放大这个闪烁临界值的两端
3:不同的动画分压不同,检测电压的实际补偿值不同,需要实测修改
4:当前的降额步幅是否会导致降额时看起来闪烁
#define POWER_DIAG_TICK (50)
#define POWER_DIAG_TIME (500)
#define MAX_UP_PART_FROM_VOLT 50 // 低压降额的最大次数
#define ONCE_UP_VAL_FROM_VOLT 1.0 // 单次电压降额比例
// ------此部分临界值由灯板外接电压表调试得出
//#define OVER_MAX_POWER 17.8f // 19.0补偿为18.5 过压保护值,过压19.0持续时间大于100ms 关闭格栅灯
#define HIGH_POWER_RECOVER 17.0f // 18补偿为17.5 过压恢复值,恢复格栅灯
#define OVER_LOW_POWER 7.5f // 欠压保护值 小于后关闭格栅灯
#define LOW_POWER_RECOVER 8.55f // 欠压后恢复到大于8.5V时,恢复欠压保护,格栅灯开启
#define TO_DOWN_POWER 9.85f // 小于10V电压开始降额
static int up_part_from_Volt = 0;
float up_pwm_From_Volt = 0;
float up_pwm_From_Volt_and_Temp = 1;
static uint8_t power_check_counter = 0;
static char BOR_Adc_Low_Count_Off = 0;
static char BOR_Adc_Low_Count_On = 0;
static char BOR_Adc_High_Count_Off = 0;
static char BOR_Adc_High_Count_On = 0;
static char Voltage_Derating_Count = 0;
char POWER_IS_LESS_than_10V = 0;
extern float up_pwm_From_Temp;
typedef enum
{
POWER_IS_DEFAULT = 0, // 默认
POWER_IS_LOW_PROTECT , // 低压保护状态
POWER_IS_LOW_RECOVER, // 低压恢复状态
POWER_IS_HIGH_PROTECT, // 高压保护状态
POWER_IS_HIGH_RECOVER, // 高压恢复状态
POWER_STATE_MAX ,
}Power_state_e;
Power_state_e POWER_state = POWER_IS_DEFAULT;
typedef enum
{
VOLT_IS_DEFAULT = 0, // 电压默认状态,不降额,如果已经降额开始恢复
VOLT_IS_LESS_than_10V // 电压小于10V,开始降额
}Voltage_Derating_state_e;
Voltage_Derating_state_e Volt_state = VOLT_IS_DEFAULT;
/*
==================================================================
*函 数 名:Power_MainFunc
*功能描述:电源ADC检测
50ms检测一次,10次放到数组里,后续进行滤波算法后给出电压值
其间100ms和500ms分别执行降额动作和更新温度值
如果当前在执行动画,给出电压值会加上不同动画的补偿值
*输入参数:
*返 回 值:
*日 期:2024/3/12
*修改记录:
==================================================================
*/
#define N 10
uint16_t power_adc_val[N];
float powerVolt=0;
void Power_MainFunc(void)
{
float pop;
// float powerVolt;
uint16_t adc_v = 0;
power_adc_val[power_check_counter] = ADC_GetArray(POWER_CHECK_SEQ); //每50ms采样填充数据到数组里面
power_check_counter++;
if(power_check_counter %2 == 0 && (power_check_counter!=0)) // 每100ms降额一次
{
do_Voltage_Derating();
}
// 累加值10次后求均值,相当于每500ms才做后面的判断
if (power_check_counter >= (POWER_DIAG_TIME / POWER_DIAG_TICK)) // 500ms执行一次
{
power_check_counter = 0;
adc_v = middleAverageFilter(&power_adc_val[0]);
pop = (float)adc_v * 5.0f / 4096; // 采样参考电压
powerVolt = pop * 5.70f ;
if(!light_mode_is_idle() )
{
switch(light_curr_mode())
{
case AAA: powerVolt += 0.2f; break; // 动画A
case BBB: powerVolt += 0.2f; break; // 动画B
}
}
Voltage_H_L_Protection(powerVolt); // 高低压保护设置状态以及灭灯
Voltage_Derating_state(powerVolt); // 判断是否满足降额条件设置状态
}
else
{
return;
}
}
/*
==================================================================
*函 数 名:Voltage_H_L_Protection
*功能描述:判断传入电压条件 是否进行执行过欠压保护动作
*输入参数:滤波后的电压值
*返 回 值:
*日 期:2024/3/12
*修改记录:
==================================================================
*/
float over_max_power = 18.5f;
void Voltage_H_L_Protection(float powerVolt)
{
// <7.5低压保护
if(powerVolt < OVER_LOW_POWER)
{
BOR_Adc_Low_Count_Off++;
if(BOR_Adc_Low_Count_Off >= 1) // 进来直接设置为低压状态
{
BOR_Adc_Low_Count_Off = 0;
if(POWER_state != POWER_IS_LOW_PROTECT)
{
POWER_state = POWER_IS_LOW_PROTECT; // 设置为低压保护状态
light_mode_stop(); // 直接使能灭灯
light_ctrl_on(0);
}
}
}
else
{
BOR_Adc_Low_Count_Off = 0; // 正常电压就清除计数器 去抖动
}
// 7.5低压保护 ----> 8.5恢复
if(powerVolt >= LOW_POWER_RECOVER)
{
BOR_Adc_Low_Count_On++;
if(BOR_Adc_Low_Count_On >= 1)
{
BOR_Adc_Low_Count_On = 0;
if(POWER_state == POWER_IS_LOW_PROTECT) // 如果之前是低压保护状态,设置为低压恢复状态
{
POWER_state = POWER_IS_LOW_RECOVER;
}
}
}
else
{
BOR_Adc_Low_Count_On = 0;
}
// 不同动画模式的过压保护值
if (powerVolt > 15) //电压大于15才判断过压
{
if(!light_mode_is_idle() )
{
switch(light_curr_mode())
{
case AAA : over_max_power = 17.7f; break;
case BBB: over_max_power = 17.8f; break;
}
}
}
// >19高压保护
if (powerVolt > over_max_power)
{
BOR_Adc_High_Count_Off++;
if(BOR_Adc_High_Count_Off >= 1) // 高压直接进来
{
BOR_Adc_High_Count_Off = 0;
if(POWER_state != POWER_IS_HIGH_PROTECT)
{
POWER_state = POWER_IS_HIGH_PROTECT;
light_mode_stop();
light_ctrl_on(0);
}
}
}
else
{
BOR_Adc_High_Count_Off = 0;
}
// 高压保护--->恢复
if(powerVolt <= HIGH_POWER_RECOVER)
{
BOR_Adc_High_Count_On++;
if(BOR_Adc_High_Count_On >= 1)
{
BOR_Adc_High_Count_On = 0;
if(POWER_state == POWER_IS_HIGH_PROTECT)
{
POWER_state = POWER_IS_HIGH_RECOVER;
}
}
}
else
{
BOR_Adc_High_Count_On = 0;
}
}
/*
==================================================================
*函 数 名:Voltage_Derating_state
*功能描述:判断传入电压条件 是否满足电压降额条件
Volt_state全局变量 给出电压是否小于10V的判断,后续通过此标志做降额动作
*输入参数:滤波后的电压值
*返 回 值:
*日 期:2024/3/12
*修改记录:
==================================================================
*/
void Voltage_Derating_state(float adcVolt)
{
// powerVolt = (powerVolt * 5.0f / 4096) * 5.7;
if(adcVolt < TO_DOWN_POWER) // 根据ADC判断是否 <10V 这里500ms进来一次
{
Voltage_Derating_Count++;
if(Voltage_Derating_Count >= 2) // 次数持续2次=1000ms进来
{
Voltage_Derating_Count = 0;
if(Volt_state != VOLT_IS_LESS_than_10V)
{
Volt_state = VOLT_IS_LESS_than_10V; // 改状态为 降额状态
}
}
}
else if(adcVolt >TO_DOWN_POWER +0.6f) // 正常电压回复条件__大于抖动筒上部分==0.6V
{
Volt_state = VOLT_IS_DEFAULT; // 改状态为 正常状态
Voltage_Derating_Count = 0;
}
}
/*
==================================================================
*函 数 名:do_Voltage_Derating
*功能描述:进行电压降额具体动作,并限制最终范围符合标准
最终系数up_pwm_From_Volt_and_Temp累乘 温度和电压的合计值
*输入参数:
*返 回 值:
*日 期:2024/3/12
*修改记录:
==================================================================
*/
void do_Voltage_Derating(void)
{
// 确定<10 执行降压降额策略
if (Volt_state == VOLT_IS_LESS_than_10V)
{
up_part_from_Volt++;
if (up_part_from_Volt > MAX_UP_PART_FROM_VOLT)
up_part_from_Volt = MAX_UP_PART_FROM_VOLT; // 电压降额最大降 50% 即比例为设定值的1-50%
up_pwm_From_Volt = 1.0f - (up_part_from_Volt * ONCE_UP_VAL_FROM_VOLT / 100.00); //printf("电压低压,降额比例 %2.2f\r\n", up_pwm_From_Volt);
}
else
{
if(up_part_from_Volt >=1 ) up_part_from_Volt--;
if(up_part_from_Volt < 0 ) up_part_from_Volt = 0;
up_pwm_From_Volt = 1.0f - (up_part_from_Volt * ONCE_UP_VAL_FROM_VOLT / 100.00); //printf("正常电压\r\n");
}
if (up_pwm_From_Volt < 0.50f) up_pwm_From_Volt = 0.50f;
if (up_pwm_From_Volt > 1.0f) up_pwm_From_Volt = 1.0f;
up_pwm_From_Volt_and_Temp = up_pwm_From_Volt * up_pwm_From_Temp;
// up_pwm_From_Volt_and_Temp = up_pwm_From_Volt ;
// up_pwm_From_Volt_and_Temp = up_pwm_From_Temp ;
if (up_pwm_From_Volt_and_Temp <= 0.30f) // 合计降额度系数最低不能低于30%
up_pwm_From_Volt_and_Temp = 0.30f;
}
/*
==================================================================
*函 数 名:middleAverageFilter
*功能描述:中位平均值滤波 连续采样N个数据,去掉2个最大值和2个最小值然后计算N-4个数据的算术平均值
*输入参数:10空间数组的首地址
*返 回 值:滤波后的值
*日 期:2024/3/12
*修改记录:
==================================================================
*/
uint16_t middleAverageFilter(uint16_t power_adc_val[])
{
uint16_t i,j,k;
uint16_t temp,sum = 0;
// 冒泡排序
for(j = 0; j < N-1; ++j)
{
for(k = 0; k < N-j-1; ++k)
{
if(power_adc_val[k] > power_adc_val[k+1])
{
temp = power_adc_val[k];
power_adc_val[k] = power_adc_val[k+1];
power_adc_val[k+1] = temp;
}
}
}
// 去2个最大 2个最小值
for(i = 2; i < N-2; ++i)
{
sum += power_adc_val[i];
}
// 返回去最大最小后的 平均值
return sum/(N-4);
}
/*
==================================================================
*函 数 名:get_downed_PWM
*功能描述:把默认的PWM值*温度*电压降额系数
*输入参数:动画抠图时预设的PWM标准值
*返 回 值:标准值*降额系数后的 PWM值
*日 期:2024/3/12
*修改记录:
==================================================================
*/
// 动画预设的PWM值 * 温度和电压降频后的系数
uint8_t get_downed_PWM(uint8_t cartoon_pwm)
{
if(up_pwm_From_Volt_and_Temp==1.0f)
{
return cartoon_pwm;
}
return cartoon_pwm * up_pwm_From_Volt_and_Temp;
}