徐依淼 发表于 2014-2-24 13:55:58

怎样用C程序能实现PID倒立摆系统?

杨鹏飞 发表于 2014-2-24 13:59:27

#include "stc12.h" #include <intrins.h>#include"pid.h" typedefunsignedcharuint8;   typedefunsignedintuint16;   typedefunsignedlong intuint32; /*********************************函数声明******************   结构体设定***********************************************************/ typedef struct PIDValue { uint32Ek_Uint32;//差值保存,给定和反馈的差值 uint8EkFlag_Uint8;//差值标志位符号,1则对应的为负数,0为对应的为正数   uint8KP_Uint8;//比例系数uint8KI_Uint8;//积分系数uint8KD_Uint8;//微分显示uint16Uk_Uint16;//上一时刻的控制电压 uint16RK_Uint16;//设定值 uint16CK_Uint16;//实际值uint8Vaule_Flag;//输出的值正负标志位,0为正,1为负}PIDValueStr; PIDValueStrPID;//定义一个结P构体uint16out ;// 加热输出(PID运算后的输出值)/*********************************************************************************** 增量型PID算式:PID :Uk=KP*+KI*E(k)+KD*函数入口: RK(设定值),CK(实际值),KP,KI,KDPID比例参数函数出口: U(K) PID运算函数 **************************************************************************************/ uint16 PID_Calc(uint16 PIDinput)   {    uint32Temp;//中间临时变量   uint32PostSum;//正数和   uint32NegSum;//负数和   Temp = 0;//给储存中间临时变量赋初值Temp = 0;   Temp = 0;   PostSum = 0;//给存储所有的正数变量赋初值NegSum= 0;//给存储所有的负值变量赋初值PID.RK_Uint16=180;//设定值为180PID.CK_Uint16=PIDinput;//输入值 if( PID.RK_Uint16 > PID.CK_Uint16 )//如果设定值大于实际值,就是当前的值比设定值小{if( PID.RK_Uint16 - PID.CK_Uint16 >10 )//计算偏差是否大于 piancha=10 ( 这里的10由 piancha 来设定大小,根据实际情况设定) //if( PID.RK_Uint16 - PID.CK_Uint16 >piancha ){//如果偏差大于 piancha=10 不在设定的PID调控范围之内就全速加热out = 100;//偏差大于piancha=10为上限幅值输出(全速加热)   // PID.Uk_Uint16 = full_speed;//全速时的加热值,更具实际情况可自由设定 这里full_speed=100; }   else//如果偏差小于 piancha=10 再调节的范围内就计算储存起来{//下面就是PID算法   Temp = PID.RK_Uint16 - PID.CK_Uint16;// 计算出当前偏差值E(k)    PID.EkFlag_Uint8=0;//E(k)为正数 的标志位 0为正,1为负//数值移位   PID.Ek_Uint32 = PID.Ek_Uint32;//存储E(k-2)PID.Ek_Uint32 = PID.Ek_Uint32;//储存E(k-1)PID.Ek_Uint32 = Temp;//存储E(k)/****************************************************************************************/   if( PID.Ek_Uint32 >PID.Ek_Uint32 )//E(k)>E(k-1) 为正数{   Temp=PID.Ek_Uint32 - PID.Ek_Uint32;//E(k)-E(k-1) 保存PID.EkFlag_Uint8=0;// 设定标志位 0为正,1为负}   else//E(k)<E(k-1)   {   Temp=PID.Ek_Uint32 - PID.Ek_Uint32;//E(k)-E(k-1)为负数   PID.EkFlag_Uint8=1;    }   /*****************************************************************************************/   Temp=PID.Ek_Uint32*2 ;// 2E(k-1)      if( (PID.Ek_Uint32+ PID.Ek_Uint32)>Temp )//E(k-2)+E(k)>2E(k-1)   {   Temp=(PID.Ek_Uint32+ PID.Ek_Uint32)-Temp;//E(k-2)+E(k)-2E(k-1)为正数   PID.EkFlag_Uint8=0;    }   else//E(k-2)+E(k)-2E(k-1)为负数   {   Temp=Temp-(PID.Ek_Uint32+ PID.Ek_Uint32);//2E(k-1)-(E(k-2)+E(k))PID.EkFlag_Uint8=1;   }   /**********************************************************************************************/   Temp = (uint32)PID.KP_Uint8 * Temp;// KP*   Temp = (uint32)PID.KI_Uint8 * PID.Ek_Uint32;// KI*E(k)   Temp = (uint32)PID.KD_Uint8 * Temp;// KD* /************************以下部分代码是讲所有的正数项叠加,负数项叠加**************************/   /**************************************KP*********************************************/   if(PID.EkFlag_Uint8==0)   PostSum += Temp;//正数和   else   NegSum += Temp;//负数和 /*************************************** KI*E(k)*************************************************/    if(PID.EkFlag_Uint8==0)   PostSum += Temp;//正数和   else   ;//空操作,E(K)>0 /************************************KD**************************************/   if(PID.EkFlag_Uint8==0)   PostSum += Temp;//正数和   else   NegSum += Temp;//负数和 /**********************************************U(K)*************************************************/   //PostSum += (uint32)PID.Uk_Uint16;      if(PostSum > NegSum )// 是否控制量为正数   {   out= PostSum - NegSum;PID.Vaule_Flag=0;//PID调节值是正值}      else//控制量输出为负数   {out=NegSum-PostSum;   PID.Vaule_Flag=1;//PID调节值是负值}   }//return out; }else//如果设定值小于实际值,就是当前的值大于设定值,就不进行PID计算直接输出 0 {   out = 0;}    return out;}
页: [1]
查看完整版本: 怎样用C程序能实现PID倒立摆系统?