#include "PID.h" #include "Relays.h" extern u16 tem; float cold_tem=0; float red_tem=0; float ti; float ki=0.001; float kd=340; extern u8 hot_clod_flag; extern u8 gpio_state; PID pid; void PID_Init() { //pid.set_tem=tem;//用户设定温度 pid.Kp=170; pid.t=500;//PID计算周期 //pid.Ti=5000000;//积分时间 //pid.Td=1000;//微分时间 pid.pwmcycle=200;//pwm周期200 pid.OUT0=1; pid.C1ms=0; } void PID_Calc() //pid计算 { float DelEk;//最近两次偏差之差 //float td; float out; if(pid.C1ms<(pid.t)) //计算周期未到 { return ; } if(pid.set_tem>pid.now_tem+1) { //得到当前的偏差值,设置温度大于实际温度,加热,关闭四通阀 //GPIO_ResetBits(GPIOA,GPIO_Pin_1);//关闭四通阀 HC595_Send_Byte(gpio_state&=0xFB);//关闭四通阀 &=1111 1011 0xFB hot_clod_flag=2; //pid.Iout=0; } if(pid.now_tem>pid.set_tem+1) { //得到当前的偏差值,设置温度小于实际温度 //GPIO_SetBits(GPIOA,GPIO_Pin_1);//打开四通阀,制冷 HC595_Send_Byte(gpio_state|=0x04);//打开四通阀,制冷 |=0000 0100 hot_clod_flag=1; //pid.Iout=0; } if(pid.set_tem>pid.now_tem) { pid.Ek=pid.set_tem-pid.now_tem; } else { pid.Ek=pid.now_tem-pid.set_tem; } pid.Pout=pid.Kp*pid.Ek; //比例输出 pid.SEk+=pid.Ek; //历史偏差总和 DelEk=pid.Ek-pid.Ek_1; //最近两次偏差之差 //ti=pid.t/pid.Ti; //ki=ti*pid.Kp; pid.Iout=ki*pid.SEk; //积分输出 // td=pid.Td/pid.t; // // kd=pid.Kp*td; pid.Dout=kd*DelEk; //微分输出 if(pid.Dout<0) { pid.Dout=0-pid.Dout; } //out= pid.Pout+ pid.Iout+ pid.Dout; out= pid.Pout+pid.Iout+ pid.Dout; if(out>pid.pwmcycle) { pid.OUT=pid.pwmcycle; } else if(out<=0) { pid.OUT=pid.OUT0; } else { pid.OUT=out; } pid.Ek_1=pid.Ek; //更新偏差 pid.C1ms=0; }