#include "PID.h" #include "Relays.h" #include "USART.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; extern int T; unsigned int num = 0; PID pid; u8 rs485speed[8] = {0x01, 0x06, 0x60, 0x00, 0x00, 0x09, 0xBB, 0xAA}; // speed control for compressor controller int min_speed_count = 1500; int max_speed_count = 6000; void PID_Init() { // pid.set_tem=tem;//用户设定温度 pid.Kp = 110; pid.Ki = 0.001; pid.Kd = 340; 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) { 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 = pid.Ki * pid.SEk; // 积分输出 // td=pid.Td/pid.t; // kd=pid.Kp*td; pid.Dout = pid.Kd * DelEk; // 微分输出 if (pid.Dout < 0) { pid.Dout = 0 - pid.Dout; } // out= pid.Pout+pid.Iout+ pid.Dout; out = pid.Pout; 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; if (pid.set_tem > pid.now_tem + 1) { // 得到当前的偏差值,设置温度大于实际温度1℃,加热,close compressor,open heater /*GPIO1->报警铃 GPIO3->heater GPIO4—>新风风扇 GPIO5->加湿器 GPIO6->compressor */ HC595_Send_Byte(gpio_state &= 0xDF);//close compressor &=1101 1111 0xDF num = 0; TIM_SetCompare3(TIM3, 0); HC595_Send_Byte(gpio_state |= 0x04); // open heater |=0000 0100 0x04 hot_clod_flag = 2; pid.Iout = 0; } else if (pid.now_tem > pid.set_tem) { // 得到当前的偏差值,设置温度小于实际温度,制冷,open compressor,close heater HC595_Send_Byte(gpio_state &= 0xFB); // close heater &=1111 1011 0xFB // 0-200对应0-100%,如果pid.out=50,占空比就是25%,//num=50*400/200=100,100/400=25% num = (((pid.OUT * 400) / pid.pwmcycle) - 1); // pid.OUT与pwm占空比的值换算 TIM_SetCompare3(TIM3, num / 4); // printf("%d\r\n",num); HC595_Send_Byte(gpio_state|=0x20);//open compressor |=0010 0000 hot_clod_flag = 1; // pid.Iout=0; } if (hot_clod_flag == 1 && T <= tem - 3) // 制冷过程中温度下降低于设定温度0.3℃ { HC595_Send_Byte(gpio_state&=0xDB);// close compressor and heater &=1101 1011 0xDB num = 0; TIM_SetCompare3(TIM3, 0); // close compressor hot_clod_flag = 0; } if (hot_clod_flag == 2 && T >= tem) // while heat, T above tem { HC595_Send_Byte(gpio_state&=0xDB);//close compressor and heater &=1101 1011 0xDB num = 0; TIM_SetCompare3(TIM3, 0); // close compressor hot_clod_flag = 0; } int out1 = pid.OUT; // speed count int speed_count = out1 / 200.0 * (max_speed_count - min_speed_count) + min_speed_count; if (speed_count > 6000) { speed_count = 6000; } rs485speed[4] = speed_count / 256; rs485speed[5] = speed_count % 256; RS485_3_Init(9600); delay_xms(100); RS485_3_Send_Data(rs485speed, 8); // RS485_1_Send_Data_1(rs485speed, 8); delay_xms(200); RS485_1_Init(9600); // HC595_Send_Byte(gpio_state&=0xDB);// close compressor and heater &=1101 1011 0xDB }