您的位置 首页 培训

根据AVR ATMega16 的PID操控算法程序

最近由于有些时间,于是想起了做一个PID设计,在网上收集了不少关于PID控制的理论,于是计划用mega16L做一个PID测试程序,发现一些意想不到的误差,不知各位同仁是否有遇到与我的类似的现象:我

  最近因为有些时刻,所以想起了做一个PID规划,在网上收集了不少关于PID操控的理论,所以方案用mega16L做一个PID测验程序,发现一些意想不到的差错,不知各位同仁是否有遇到与我的相似的现象:我界说了一个PID结构体,在初始化的时分无法把每个元素的初始化值设置为0(见下面的仿真图),并且,PID结构体中的部分参数是应该不变的,在整个PID运算中,可是不应该改变的参数却在PID运算发生了改变,不知道是什么原因,到现在也无法查出原因。有爱好的朋友能够一同参加评论或有经历的朋友 给与相关协助,谢谢!

  具体的代码和仿真状况如下:(我的硬件体系是本站的min Mega16/32 + JTAG ICE)

  #include "config.h"

  struct _PID

  {

  float PVn; //反应信号变量

  float SPn; //设定值

  float Mn; //PID运算成果

  float Kc; //份额系数

  float Ts; //采样时刻(ms)

  float Ti; //积分时刻(ms)

  float Td; //微分时刻(ms)

  float Mx; //积分项调整参数

  float PVn_1;//前一次反应变量

  float MPn; //份额项的成果值

  float MIn; //积分项的成果值

  float MDn; //微分项的成果值

  };

  struct _PID *myPID;

  void init_myPID(void);

  void init_ports(void);

  void init_device(void);

  float MPn_value(struct _PID *PID);

  float MIn_value(struct _PID *PID);

  float MDn_value(struct _PID *PID);

  float Mx_value(struct _PID *PID);

  float Mn_value(struct _PID *PID);

  void main (void)

  {

  init_device();

  init_myPID();

  myPID->SPn = 155.5;

  myPID->Kc = 13.2;

  myPID->Ts = 0.2;

  myPID->Ti = 600.0;

  myPID->Td = 0.0;

  myPID->PVn = 108.2;

  while(1)

  {

  myPID->MPn = MPn_value(myPID);

  myPID->MDn = MDn_value(myPID);

  myPID->Mx = Mx_value(myPID);

  myPID->MIn = MIn_value(myPID);

  myPID->Mn = Mn_value(myPID);

  myPID->PVn_1 = myPID->PVn;

  }

  }

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

  void init_myPID(void)

  {

  myPID->PVn = 0.0;

  myPID->SPn = 0.0;

  myPID->Mn = 0.0;

  myPID->Kc = 0.0;

  myPID->Ts = 0.0;

  myPID->Ti = 0.0;

  myPID->Td = 0.0;

  myPID->Mx = 0.0;

  myPID->PVn_1 = 0.0;

  myPID->MPn = 0.0;

  myPID->MIn = 0.0;

  myPID->MDn = 0.0;

  }

  //——————————————————————————

  void init_ports(void)

  {

  PORTA = 0x00; //If ADC Function was be used,the PORTA could`t set bit 1

  DDRA = 0x00; //the port set input mode.

  PORTB = 0x00;

  DDRB = 0x00;

  PORTC = 0x00; //m103 output only

  DDRC = 0x00;

  PORTD = 0x00;

  DDRD = 0x00;

  }

  //——————————————————————————

  void init_device(void)

  {

  CLI();

  init_ports();

  MCUCR = 0x00; //Set Power control(State:Close)

  GICR = 0x00; //Set boot guide(State:Close).

  SEI(); //re-enable interrupts

  //all peripherals are now initialized

  }

  // 核算 份额项的值

  //——————————————————————————

  float MPn_value(struct _PID *PID)

  {

  float myMPn = 0.0;

  myMPn = PID->Kc *( PID->SPn – PID->PVn);

  return myMPn;

  }

  //核算积分项的值

  //——————————————————————————

  float MIn_value(struct _PID *PID)

  {

  float myMIn = 0.0;

  myMIn = PID->Kc*(PID->Ts/PID->Ti)*(PID->SPn – PID->PVn) + PID->Mx;

  return myMIn;

  }

  //核算微分项的值

  //——————————————————————————

  float MDn_value(struct _PID *PID)

  {

  float myMDn = 0.0;

  myMDn = PID->Kc * (PID->Td/PID->Ts) * (PID->PVn_1 – PID->PVn);

  return myMDn;

  }

  //核算PID的成果

  //——————————————————————————

  float Mn_value(struct _PID *PID)

  {

  float myMn = 0.0;

  myMn = PID->MPn + PID->MIn + PID->MDn;

  return myMn;

  }

  //核算积分项的调整值

  //——————————————————————————

  float Mx_value(struct _PID *PID)

  {

  float myMx = 0.0;

  if(PID->Mn > 1.0)

  {

  myMx = 1.0 – (PID->MPn + PID->MDn);

  }

  else if(PID->Mn < 0.0)

  {

  myMx = -(PID->MPn + PID->MDn);

  }

  return myMx;

  }

  

 

  运转到PID初始化函数:void init_myPID(void)时的仿真成果如下:无法悉数初始化为0

  

 

  运转到:

  myPID->SPn = 155.5;

  myPID->Kc = 13.2;

  myPID->Ts = 0.2;

  myPID->Ti = 600.0;

  myPID->Td = 0.0;

  myPID->PVn = 108.2;

  从头赋值后,部分参数Ts并不为0.2

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/changshang/peixun/299136.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部