大体分为3个步骤
1:ADC判断临界物理值是否达到---多次检测滤波->确定当前状态
2:确定状态后进行阶梯递减或者差值递减,使用一个系数作为PWM的阶梯值接口
3:计算出降额系数,乘PWM的周期放到占空比寄存器(系数为1认为是满占空比,0.5认为是半占空比)
#define NTC_DIAG_TICK (50)
#define NTC_DIAG_TIME (500)
#define MAX_UP_PART_FROM_TEMP 50 // 温度降额的最大次数
#define ONCE_UP_VAL_FROM_TEMP 1.0 // 单次温度降额比例
typedef enum
{
NORMAL_TEMP = 0, // 正常温度状态
OVER_TEMP // 过温状态
}Temp_state_e;
Temp_state_e Temp_state = NORMAL_TEMP; // 默认正常温度
int over_temp_part[3] = {0}; // 超过的温度数量值
int temp_board[3] = {0}; // 0 驱动板 1左灯 2右灯板int over_Temp_Driver_board = 90; // 默认90度认为过温
int over_Temp_Light_board = 85;
float up_pwm_From_Temp = 0; // 温度降额系数
/*
==================================================================
*函 数 名:NTC_Check_MainFunc
*功能描述:轮询检测3个灯板的温度
50ms检测一次,累计10次做平均值滤波,500ms更新温度值
其间100ms和500ms分别执行降额动作和更新温度值
*输入参数:
*返 回 值:
*日 期:2024
*修改记录:
==================================================================
*/
void NTC_Check_MainFunc(void)
{
uint16_t ntc_adc_val[3] = {0};
uint8_t adc_seq = 0;
for(adc_seq = 0; adc_seq < 3; adc_seq++)
{
ntc_adc_val[adc_seq] = ADC_GetArray(DRIVER_TEMP_CHECK_SEQ + adc_seq);
ntc_array_counter[adc_seq] += ntc_adc_val[adc_seq];
ntc_check_counter[adc_seq]++;
if(ntc_check_counter[adc_seq] %2 ==0 && ntc_check_counter[adc_seq]!=0) // 100ms执行一次降额
{
do_Temp_Protection(ntc_adc_val[adc_seq]); //---具体执行过温升降额操作的函数
}
if(ntc_check_counter[adc_seq] >= (NTC_DIAG_TIME / NTC_DIAG_TICK)) // 该部分10 * 50 == 500ms执行一次
{
ntc_adc_val[adc_seq] = (ntc_array_counter[adc_seq] / ntc_check_counter[adc_seq]);
ntc_check_counter[adc_seq] = 0;
ntc_array_counter[adc_seq] = 0;
temp_board[adc_seq] = Get_temper(ntc_adc_val[adc_seq]);
if(temp_board[adc_seq]<-19 ) // 低温超出范围恒返回-20度
{
temp_board[adc_seq] = -20;
}
Temp_Protection_part( temp_board[adc_seq] ,adc_seq); // 500ms更新当前是否过温
}
}
}
/*
==================================================================
*函 数 名:Temp_Protection_part
*功能描述:计算3个灯板与目标温度的最大差值 该函数500ms调用一次
*输入参数:temp(当前灯板摄氏温度) adc_seq(灯板序号)
*返 回 值:全局变量-->MAX_over_temp_part(最大差值份数,每份后续降2%)
*日 期:2024
*修改记录:
==================================================================
*/
void Temp_Protection_part(int temp,uint8_t adc_seq)
{
if(adc_seq==0)
{
if(temp >= over_Temp_Driver_board)
over_temp_part[adc_seq] = temp - over_Temp_Driver_board; //驱动板大于90度进行调节
else over_temp_part[adc_seq] = 0;
}
else if(adc_seq==1 || adc_seq==2)
{
if(temp >= over_Temp_Light_board)
over_temp_part[adc_seq] = temp - over_Temp_Light_board; //两灯板大于85度进行调节
else over_temp_part[adc_seq] = 0;
}
// 取3个板温度与其变频温度最大的差值
MAX_over_temp_part = over_temp_part[0] > over_temp_part[1] ? over_temp_part[0] : over_temp_part[1] ;
MAX_over_temp_part = MAX_over_temp_part > over_temp_part[2] ? MAX_over_temp_part : over_temp_part[2] ;
if(MAX_over_temp_part < 0 )
MAX_over_temp_part = 0;
// 更新是否过温状态
if(MAX_over_temp_part>0)
Temp_state = OVER_TEMP; // 过温
else
Temp_state = NORMAL_TEMP;
}
/*
==================================================================
*函 数 名:do_Temp_Protection
*功能描述:执行温度降额动作__最终给出温度降额系数 100ms调用一次
*输入参数:灯板的ADC采样值(0-4095)
*返 回 值:全局变量-->up_pwm_From_Temp(温度降额系数)
*日 期: 2024.3
*修改记录:2024 改每低1%降恒定数值逻辑为过温持续阶梯降频 至温度正常开始阶梯回复
2024.4修改:为降低抖动,降低降频步幅由2%至1%,保持100ms调节一次 放宽最大时间至5S,
==================================================================
*/
void do_Temp_Protection( uint16_t adc_val)
{
if(Temp_state == OVER_TEMP)
{
up_part_from_Temp ++; // 温度降频阶段
if(up_part_from_Temp >MAX_UP_PART_FROM_TEMP) up_part_from_Temp = MAX_UP_PART_FROM_TEMP; // 温度降额次数最多降到50%
up_pwm_From_Temp = 1.0f - (up_part_from_Temp * ONCE_UP_VAL_FROM_TEMP /100.00);//每次减1%
}
else
{
if(up_part_from_Temp >=1) // 温度正常后的电流恢复阶段
up_part_from_Temp --;
if(up_part_from_Temp < 0) up_part_from_Temp = 0;
up_pwm_From_Temp = 1.0f - (up_part_from_Temp * ONCE_UP_VAL_FROM_TEMP / 100.00);
}
if(up_pwm_From_Temp>1.0f) up_pwm_From_Temp = 1.0f;
if(adc_val>4080 || adc_val<5) up_pwm_From_Temp = 0.80f; // NTC开路或者短路_温度降额系数为80%
if(up_pwm_From_Temp< 0.5f) up_pwm_From_Temp = 0.5f; // 降额系数最低不能低于50%
}