|||
很长时间没有更新blog了
另外有个事情比较抱歉,由于有阵子sina的邮箱不好用,所以我改用了gmail的邮箱,结果今天突然看看sina的邮箱,发现有不少朋友管我要9200的protel文件以及pid的程序,我想我干脆直接贴在这里吧,希望这点信息对那些朋友还有用。
// 数据全部采用long型,最后的两位表示小数
struct _pid
{
long set_point; //设定值
long ek0; //当前误差
long ek1; //上一次误差
long ek2; //上上次误差
long uk0; //当前输出
long uk1; //上一次输出
long kp;
long ki;
long kd;
};
void pid_init(void)
{
pid.set_point = parameters.cur_set_point_temp;
pid.kp = (long) (parameters.p);
pid.ki = (long) (parameters.i);
pid.kd = (long) (parameters.d);
pid.ek0 = 0;
pid.ek1 = 0;
pid.ek2 = 0;
pid.uk0 = 0;
pid.uk1 = 0;
ad_scall = parameters.ad_zero_value - parameters.ad_full_value; //软件校后的采样数据范围
}
// 改进型的pid算法,积分的范围有限制,可以有效改善稳定过程中的过冲
void pid_output_caculate(void)
{
// 计算本次误差
pid.ek0 = (long) pid.set_point * 10 - (long) current_temp;
deltauk = pid.kp * (pid.ek0 - pid.ek1) / 100;
// 在3度范围才进行积分
if(abs(pid.ek0) < 300)
{
deltauk += pid.ki * pid.ek0 / 1000;
}
// 加上微分量
deltauk += pid.kd * (pid.ek2 + pid.ek0 - 2 * pid.ek1) / 100;
// 得到当前输出
pid.uk0 = pid.uk1 + deltauk;
// 保存当前的数据
pid.ek2 = pid.ek1;
pid.ek1 = pid.ek0;
pid.uk1 = pid.uk0;
}