121 lines
2.9 KiB
C
121 lines
2.9 KiB
C
/*
|
||
* PID.c
|
||
*
|
||
* Created on: 2022年03月22日
|
||
* Author: User
|
||
*/
|
||
|
||
#include <Main.h>
|
||
|
||
#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;
|
||
}
|