首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

基于AVR ATMega16 的PID 控制算法程序

基于AVR ATMega16 的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
返回列表