c语言写好的pid函数 温控pid算法实例c语言

PID算法的C语言实现

基本流程

目前成都创新互联已为上千家的企业提供了网站建设、域名、网络空间、网站托管、服务器托管、企业网站设计、钟山网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。

积分环节:主要是用来消除 静差 (系统稳定后输出值和设定值之间的差值,积分环节实际上就是偏差累积的过程,把累积的误差加到原来系统上以抵消系统造成的静差)

微分环节:反映了偏差信号的变化规律,根据偏差信号的变化规律来进行超前调节,从而增加系统的快速性

对上述公式进行离散化(采样):两个公式

增量型PID:

通过增量型PID公式可以看出,最终表达结果和最近三次的偏差有关,最终输出结果应该为:

首先定义结构变量体:

然后初始化变量

最后编写控制算法

基本算法,没有考虑死区问题,没有设定上下限

在启动、结束或大幅度增减设定时,短时间内系统输出有很大的偏差,会造成PID运算的积分积累,导致控制量超过执行机构可能允许的最大动作范围对应的极限控制量,从而引起较大的超调,甚至是振荡。

为了克服这个问题,引入积分分离的概念,即当被控量和设定值偏差较大时,取消积分作用;当被控量接近设定值时,引入积分控制,以消除静差,提高精度。

abs :绝对值

令index=0使积分环节失效

积分饱和现象:如果系统存在一个方向的偏差,PID控制器的输出由于积分作用的不断累加而加大,从而导致执行机构达到极限位置。此时计算器输出量超出正常运行范围而进入饱和区,一旦系统出现反向偏差,输出量将逐渐从饱和区退出,进入饱和区越深则退出饱和区时间越长,在这段时间里,执行机构仍然停留在极限位置而不随偏差反向而立即做出相应改变,造成性能恶化。

采用梯形积分能够减小余差,提高精度

改变积分系数,若偏差大,积分作用减弱,系数减小;若偏差小,积分作用增强,系数增大。

变积分PID的基本思想是设法改变积分项的累加速度,使其与偏差大小对应。

使整个系统的稳定速度非常快

比例系数Kp的作用是加快系统的响应速度提高系统的调节精度

积分系数Ki的作用是消除系统的稳态误差

微分系数Kd的作用是改善系统的动态特性

反应系统性能的两个参数是系统误差和误差变化律

求一个单片机C语言编写的PID控制程序。谢谢!!

#include stdlib.h

#include "global_varible.h"

/****************************************************************************

* 模块名: PID

* 描述: PID调节子程序

* 采用PID-PD算法。在偏差绝对值大于△e时,用PD算法,以改善动态品质。

* 当偏差绝对值小于△e时,用PID算法,提高稳定精度。

* PIDout=kp*e(t)+ki*[e(t)+e(t-1)+...+e(1)]+kd*[e(t)-e(t-1)]

*============================================================================

* 入口: 无

* 出口: 无

* 改变: PID_T_Run=加热时间控制

*****************************************************************************/

void PID_Math(void)

{

signed long ee1; //偏差一阶

//signed long ee2; //偏差二阶

signed long d_out; //积分输出

if(!Flag_PID_T_OK)

return;

Flag_PID_T_OK=0;

Temp_Set=3700; //温度控制设定值37.00度

PID_e0 = Temp_Set-Temp_Now; //本次偏差

ee1 = PID_e0-PID_e1; //计算一阶偏差

//ee2 = PID_e0-2*PID_e1+PID_e2; //计算二阶偏差

if(ee1 500) //一阶偏差的限制范围

ee1 = 500;

if(ee1 -500)

ee1 = -500;

PID_e_SUM += PID_e0; //偏差之和

if(PID_e_SUM 200) //积分最多累计的温差

PID_e_SUM = 200;

if(PID_e_SUM -200)

PID_e_SUM = -200;

PID_Out = PID_kp*PID_e0+PID_kd*ee1; //计算PID比例和微分输出

if(abs(PID_e0) 200) //如果温度相差小于1.5度则计入PID积分输出

{

if(abs(PID_e0) 100) //如果温度相差大于1度时积分累计限制

{

if(PID_e_SUM 100)

PID_e_SUM = 100;

if(PID_e_SUM -100)

PID_e_SUM = -100;

}

d_out = PID_ki*PID_e_SUM; //积分输出

if(PID_e0 -5) //当前温度高于设定温度0.5度时积分累计限制

{

if(PID_e_SUM 150)

PID_e_SUM = 150;

if(PID_e_SUM 0) //当前温度高于设定温度0.5度时削弱积分正输出

d_out = 1;

}

PID_Out += d_out; //PID比例,积分和微分输出

}

else

PID_e_SUM=0;

PID_Out/=100; //恢复被PID_Out系数放大的倍数

if(PID_Out 200)

PID_Out=200;

if(PID_Out0)

PID_Out=0;

if(PID_e0 300) //当前温度比设定温度低3度则全速加热

PID_Out=200;

if(PID_e0 -20) //当前温度高于设定温度0.2度则关闭加热

PID_Out=0;

Hot_T_Run=PID_Out; //加热时间控制输出

PID_e2 = PID_e1; //保存上次偏差

PID_e1 = PID_e0; //保存当前偏差

}

////////////////////////////////////////////////////////////void PID_Math() end.

用C语言编写的PI调节器函数,采用位置式算法,求大神指教

typedef struct{  

float limit;    //输出限幅  

float target;   //设置量  

float feedback; //实测量  

float Kp;       //比例系数

float Ki;       //积分系数

float Kd;       //微分系数

float eSum;     //误差积分

float e0;       //当前误差  

float e1;       //上一次误差  

}PIDType;  

#define max(a, b)           (ab? a:b)  

#define min(a, b)           (ab? a:b)  

#define range(x, a, b)      (min(max(x, a), b))  

float pid_pos_update(PIDType *p)  

{  

float pe, ie, de;  

float out=0;  

//计算当前误差  

p-e0 = p-target - p-feedback;  

//误差积分  

p-eSum += p-e0;  

//误差微分  

de = p-e0 - p-e1;  

pe = p-e0;  

ie = p-eSum;  

p-e1 = p-e0;  

//数据增量  

out = pe*(p-Kp) + ie*(p-Ki) + de*(p-Kd);  

//输出限幅  

out = range(out, -p-limit, p-limit);  

return out;  

}


文章名称:c语言写好的pid函数 温控pid算法实例c语言
路径分享:http://ybzwz.com/article/dodegec.html