/* * PID.c * * Created on: 2022年03月22日 * Author: User */ #include #define kp 13.2 //比例 #define ki 0.067 //积分 #define kd 35 //微分 //#define pidtime 6 // pid周期= pidtime * 50ms,至少300ms,否则6675无法工作 #define iloss 10 //积分分离阈值,双极性 sint16_t xdata ek1[2]; // ek0当前误差,ek1上次误差 sint16_t xdata uk1; // pid计算输出值,规格化[0,100] sint32_t xdata iek1; //误差积分,分离式 sint16_t xdata ek2[2]; // ek0当前误差,ek1上次误差 sint16_t xdata uk2; // pid计算输出值,规格化[0,100] sint32_t xdata iek2; //误差积分,分离式 static void Init(void); static uint8_t Realize(uint8_t CHANNEL, uint16_t temp_val); PID_t xdata PID_Func = { Init, Realize}; static void Init(void) { ek1[0] = 0; ek1[1] = 0; uk1 = 0; iek1 = 0; ek2[0] = 0; ek2[1] = 0; uk2 = 0; iek2 = 0; } /** * @brief PID算法实现 * @param CHANNEL 通道 Temp_Setting 目标值 * @note 无 * @retval 通过PID计算后的输出 */ static uint8_t Realize(uint8_t CHANNEL, uint16_t Temp_Setting) { if (CHANNEL == Temp1_CHANNEL) { ek1[1] = ek1[0]; ek1[0] = Temp_Setting - ADC.Temp1_Result; // 计算本次偏差 if (ek1[0] <= (-iloss) || Temp_Setting == 0) { iek1 = 0; return 0; } else if (ek1[0] >= iloss) { iek1 = 0; return 100; } else if (ek1[0] > (-iloss) && ek1[0] < iloss) // 积分分离 { iek1 += ek1[0]; uk1 = ek1[0] * kp + iek1 * ki + (ek1[0] - ek1[1]) * kd; // PID运算 if (uk1 <= 0) { if (ek1[0] < 0) iek1 -= ek1[0]; uk1 = 0; } if (uk1 >= 100) { if (ek1[0] > 0) iek1 -= ek1[0]; uk1 = 100; } return uk1; } } else if (CHANNEL == Temp2_CHANNEL) //通道2计算 { ek2[1] = ek2[0]; ek2[0] = Temp_Setting - ADC.Temp2_Result; // 计算本次偏差 if (ek2[0] <= (-iloss) || Temp_Setting == 0) { iek2 = 0; return 0; } else if (ek2[0] >= iloss) { iek2 = 0; return 100; } if (ek2[0] > (-iloss) && ek2[0] < iloss) // 积分分离 { iek2 += ek2[0]; uk2 = ek2[0] * kp + iek2 * ki + (ek2[0] - ek2[1]) * kd; // PID运算 if (uk2 <= 0) { if (ek2[0] < 0) iek2 -= ek2[0]; uk2 = 0; } if (uk2 >= 100) { if (ek2[0] > 0) iek2 -= ek2[0]; uk2 = 100; } return uk2; } } return FALSE; }