|
发表于 2010-3-15 16:37:46
|
显示全部楼层
写的有些复杂,先收下了
下面是我的PID程序,使用在Atmega16上,ICCAVR
#define Kp (long)500 //MP项放大1000倍
#define Ti 200 //ms //Mi项放大1000倍
#define Tc 1 //ms
int ucOCR=0;
unsigned int ad[10]={0,0,0,0,0,0,0,0,0,0};
//在定时中断中处理(定时周期=Tc)
#pragma interrupt_handler timer0_ovf_isr:iv_TIMER0_OVF
void timer0_ovf_isr(void)
{
int Ef0=0;
static long Mi=0;
long Mp=0;
unsigned char i;
unsigned char cSREG = SREG; /* 保存全局中断标志*/
_CLI(); /* 禁止中断*/
ad[1] = read_adc(1);//读取控制目标当前AD值
Ef0 = DestAD - ad[1] ;//DestAD为控制目标的预期AD值
Mp = Kp * Ef0;
//遇限制消弱积分法
if(Mi<=0)
{
if(Ef0>0) Mi += Mp * Tc / Ti;
}
else if(Mi>=255000)
{
if(Ef0<0) Mi += Mp * Tc / Ti;
}
else
Mi += Mp * Tc / Ti;
ucOCR = (Mp + Mi)/1000 ;
if(ucOCR>0xFF) ucOCR=0xFF;//ucOCR的有效范围为0~0xFF
else if(ucOCR<0) ucOCR=0;
OCR2 = ucOCR;//控制PWM输出
SREG = cSREG; /* 恢复全局中断标志*/
} |
|