int SetPoint// 设定目标 Desired value
int Proportion// 比例常数 Proportional Const
int Integral// 积分常数 Integral Const
int Derivative// 微分常数 Derivative Const
unsigned int LastError// Error[-1]
unsigned int PrevError// Error[-2]
unsigned int SumError// Sums of Errors
// double Lastout //上次输出
unsigned int E1 // e1>e2
unsigned int E2 //
int Pmax//上限
int Pmin//下限
} PID
/*====================================================================================================
PID计算部分,遇限消弱积分PID防饱和,积分分离算法实现
=====================================================================================================*/
int PIDCalc( PID *pp, unsigned int NextPoint )
{
int dError,
Error
Error = pp->SetPoint - NextPoint //偏差
if (Error<=-pp->E1) return (pp->Pmin) //饱和
else if (Error>=pp->E1)
return (pp->Pmax)
else
{
dError = pp->LastError - pp->PrevError// 当前微分
pp->PrevError = pp->LastError
pp->LastError = Error
if (Error>=pp->E2||Error<=-pp->E2) //分离
return (pp->Proportion * Error // 比例项
+ pp->Derivative * dError )//PD,考虑限幅
else //位置式
{
pp->SumError += Error // 积分
return (pp->Proportion * Error // 比例项
+ pp->Integral * pp->SumError // 积分项
+ pp->Derivative * dError // 微分项 //PID
)
}
}
}
最近在用2812编程,遇到一个问题,想请教各位高手,我先说一下自己的一点理解请教高手指点。PIE一般用到的中断组是INT1-INT12。我们知道他们的优先级顺序是INT1>INT2>INT3…INT11>INT12。在开所有中断使能的前提下,如果不同组(如INT1组的TINT0和INT2组的T1CINT)的中断同时向PIE发出中断请求,那么PIE会放中断优先级较高(INT1.TINT0)的中断过去。同样的在如果是同组的中断请求同时到达的话(如INT2组的),那么也同样按照PIE中断向量表查看同组优先级,CPU响应优先级较高的中断。
我的理解是,
(1)不同组之间的中断可以实现中断嵌套。如INT1组的TINT0和INT2组的T1CINT。当CPU正在响应INT2组的T1CINT中断服务程序这时如果产生了INT1组的TINT0中断的话那么CPU便会产生中断嵌套,先停下T1CINT转而去执行TINT0,
当TINT0中断服务程序执行完之后再去执行剩余没有执行网的INT1中断服务程序。
(2)同组之间的中断不可以实现中断嵌套。如果同样是INT1组的两个中断比如ADCINT和TINT0。当CPU正在响应INT1的中断服务程序时,这时如果产生了ADCINT,尽管ADCINT在INT1组中的优先级比TINT0的优先级高,还是不会产生中断嵌套。
因为同组的中断在向CPU发出中断请求之前先要经过PIE中的应答位PIEACK验证,如果PIEACK为1说明此时正有改组的中断正在响应,PIE不会放响应该发出中断请求的中断源通过,只有等到正在响应的中断服务程序执行完才会去响应刚刚
发出中断请求的中断服务程序。这也就是为什么,我们在中断服务程序的后面都要加上一句PieCtrl.PIEACK.bit.ACKx=1就是为了让应答位清零,可以响应同组的其他中断。
以上两点是我对2812中断嵌套的一点理解,尤其是提到的第(2)点,万望高手不吝指导。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)