generated from hulk/gd32f4xx_template_cmake_vscode
Heater: setpoint ramping to suppress thermal-lag overshoot
This commit is contained in:
+24
-3
@@ -19,7 +19,8 @@
|
||||
/* 内部状态 */
|
||||
|
||||
static bool s_enable = false; /* 加热使能(M3) */
|
||||
static float s_target = 0.0f; /* 目标温度(M4) */
|
||||
static float s_target = 0.0f; /* 目标温度(M4,外部设定值) */
|
||||
static float s_ramp_target = 0.0f; /* 内部斜坡目标(以 HEATER_RAMP_CPS 滑向 s_target) */
|
||||
static uint8_t s_duty10 = 0; /* 量化占空档位 0~10(x10%) */
|
||||
static bool s_overtemp = false; /* 过温锁存(滞回恢复) */
|
||||
static float s_integral = 0.0f; /* PID 积分项 */
|
||||
@@ -91,9 +92,22 @@ static void pid_compute(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* 目标斜坡:内部设定值以受限速率滑向 s_target。
|
||||
满功率爬升段 ramp 超前于实际温升(不受影响);接近目标后 ramp 先到站停住,
|
||||
误差随实际温度逼近而平滑收缩 -> 功率缓退,抑制热传导滞后造成的过冲。 */
|
||||
float diff = s_target - s_ramp_target;
|
||||
float step = HEATER_RAMP_CPS * (HEATER_PID_PERIOD_MS / 1000.0f);
|
||||
if (diff > step) {
|
||||
s_ramp_target += step;
|
||||
} else if (diff < -step) {
|
||||
s_ramp_target -= step;
|
||||
} else {
|
||||
s_ramp_target = s_target;
|
||||
}
|
||||
|
||||
/* 位置式 PID(带抗积分饱和):输出饱和时积分仅沿退饱和方向更新,
|
||||
防止升温段积分顶满后长时间维持 100% 输出(此前实测目标 50℃ 冲到 59℃) */
|
||||
float err = s_target - t;
|
||||
float err = s_ramp_target - t;
|
||||
float u_noi = HEATER_PID_KP * err
|
||||
+ HEATER_PID_KD * (err - s_prev_err); /* 比例 + 微分 */
|
||||
float integ_new = s_integral + err;
|
||||
@@ -150,7 +164,14 @@ void heat_task(void) {
|
||||
void heat_set_enable(bool on) {
|
||||
if (s_enable == on) return; /* 幂等 */
|
||||
s_enable = on;
|
||||
if (!on) {
|
||||
if (on) {
|
||||
/* 从当前实际温度起坡,避免内部目标从 0 跳变造成功率冲击 */
|
||||
s_ramp_target = ntc_get_temperature();
|
||||
if (s_ramp_target < 0.0f) {
|
||||
s_ramp_target = 0.0f; /* 传感器故障标记值非法,退化为 0 */
|
||||
}
|
||||
} else {
|
||||
s_ramp_target = 0.0f;
|
||||
s_duty10 = 0;
|
||||
pid_reset();
|
||||
heat_out(false);
|
||||
|
||||
Reference in New Issue
Block a user