|
|
#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;
|
|
|
|
|
|
void PID_Init()
|
|
|
{
|
|
|
// pid.set_tem=tem;//用户设定温度
|
|
|
pid.Kp = 110;
|
|
|
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 = 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;
|
|
|
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℃,加热,关闭压缩机,打开加热棒
|
|
|
/*GPIO1->报警铃 GPIO6->压缩机 GPIO3->加热棒 GPIO4—>新风风扇 GPIO5->加湿器 */
|
|
|
// HC595_Send_Byte(gpio_state&=0xDF);//关闭压缩机 &=1101 1111 0xDF
|
|
|
TIM_SetCompare3(TIM3, 0);
|
|
|
HC595_Send_Byte(gpio_state |= 0x04); // 打开加热棒 |=0000 0100 0x04
|
|
|
hot_clod_flag = 2;
|
|
|
pid.Iout = 0;
|
|
|
}
|
|
|
if (pid.now_tem > pid.set_tem)
|
|
|
{
|
|
|
// 得到当前的偏差值,设置温度小于实际温度,制冷,打开压缩机,关闭加热棒
|
|
|
HC595_Send_Byte(gpio_state &= 0xFB); // 关闭加热棒 &=1111 1011 0xFB
|
|
|
num = (((pid.OUT * 400) / pid.pwmcycle) - 1); // 请问这个pid.OUT与pwm占空比的值是如何换算过来的
|
|
|
TIM_SetCompare3(TIM3, num);
|
|
|
// printf("%d\r\n",num);
|
|
|
// 0-200对应0-100%,如果pid.out=50,占空比就是25%,//num=50*400/200=100,100/400=25%
|
|
|
// HC595_Send_Byte(gpio_state|=0x20);//打开压缩机 |=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);//关闭压缩机 关闭加热棒 &=1101 1101 0xDB
|
|
|
TIM_SetCompare3(TIM3, 0); // 关闭压缩机
|
|
|
HC595_Send_Byte(gpio_state &= 0xFB); // 关闭加热棒
|
|
|
hot_clod_flag = 0;
|
|
|
}
|
|
|
|
|
|
if (hot_clod_flag == 2 && T >= tem)
|
|
|
{
|
|
|
// HC595_Send_Byte(gpio_state&=0xDB);//关闭压缩机 关闭四通阀 &=1101 1101 0xDB
|
|
|
TIM_SetCompare3(TIM3, 0); // 关闭压缩机
|
|
|
HC595_Send_Byte(gpio_state &= 0xFB); // 关闭加热棒
|
|
|
hot_clod_flag = 0;
|
|
|
}
|
|
|
}
|