基于AVR ATMega16 的PID控制算法程序
最近由于有些時(shí)間,于是想起了做一個(gè)PID設(shè)計(jì),在網(wǎng)上收集了不少關(guān)于PID控制的理論,于是計(jì)劃用mega16L做一個(gè)PID測(cè)試程序,發(fā)現(xiàn)一些意想不到的誤差,不知各位同仁是否有遇到與我的類似的現(xiàn)象:我定義了一個(gè)PID結(jié)構(gòu)體,在初始化的時(shí)候無(wú)法把每個(gè)元素的初始化值設(shè)置為0(見下面的仿真圖),而且,PID結(jié)構(gòu)體中的部分參數(shù)是應(yīng)該不變的,在整個(gè)PID運(yùn)算中,但是不應(yīng)該變化的參數(shù)卻在PID運(yùn)算發(fā)生了變化,不知道是什么原因,到現(xiàn)在也無(wú)法查出原因。有興趣的朋友可以一起參與討論或有經(jīng)驗(yàn)的朋友 給與相關(guān)幫助,謝謝!
本文引用地址:http://2s4d.com/article/201609/297088.htm詳細(xì)的代碼和仿真情況如下:(我的硬件系統(tǒng)是本站的min Mega16/32 + JTAG ICE)
#include "config.h"
struct _PID
{
float PVn; //反饋信號(hào)變量
float SPn; //設(shè)定值
float Mn; //PID運(yùn)算結(jié)果
float Kc; //比例系數(shù)
float Ts; //采樣時(shí)間(ms)
float Ti; //積分時(shí)間(ms)
float Td; //微分時(shí)間(ms)
float Mx; //積分項(xiàng)調(diào)整參數(shù)
float PVn_1;//前一次反饋?zhàn)兞?/p>
float MPn; //比例項(xiàng)的結(jié)果值
float MIn; //積分項(xiàng)的結(jié)果值
float MDn; //微分項(xiàng)的結(jié)果值
};
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
}
// 計(jì)算 比例項(xiàng)的值
//------------------------------------------------------------------------------
float MPn_value(struct _PID *PID)
{
float myMPn = 0.0;
myMPn = PID->Kc *( PID->SPn - PID->PVn);
return myMPn;
}
//計(jì)算積分項(xiàng)的值
//------------------------------------------------------------------------------
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;
}
//計(jì)算微分項(xiàng)的值
//------------------------------------------------------------------------------
float MDn_value(struct _PID *PID)
{
float myMDn = 0.0;
myMDn = PID->Kc * (PID->Td/PID->Ts) * (PID->PVn_1 - PID->PVn);
return myMDn;
}
//計(jì)算PID的結(jié)果
//------------------------------------------------------------------------------
float Mn_value(struct _PID *PID)
{
float myMn = 0.0;
myMn = PID->MPn + PID->MIn + PID->MDn;
return myMn;
}
//計(jì)算積分項(xiàng)的調(diào)整值
//------------------------------------------------------------------------------
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;
}
運(yùn)行到PID初始化函數(shù):void init_myPID(void)時(shí)的仿真結(jié)果如下:無(wú)法全部初始化為0
運(yùn)行到:
myPID->SPn = 155.5;
myPID->Kc = 13.2;
myPID->Ts = 0.2;
myPID->Ti = 600.0;
myPID->Td = 0.0;
myPID->PVn = 108.2;
重新賦值后,部分參數(shù)Ts并不為0.2
評(píng)論