OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2219|回复: 1

有几个PID问题想请教下?希望大家会的不吝解答。在此表示感谢。

[复制链接]

23

主题

86

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
299
金钱
299
注册时间
2019-7-20
在线时间
108 小时
发表于 2019-9-2 11:15:27 | 显示全部楼层 |阅读模式
1金钱
1、是这样的,我用两个STM32单片机,1号单片机STM32单片机发生频率F,2号单片机测量这个频率,通过2号单片机设定目标频率,通过PID算法控制,控制DAC输出电压,1号单片机通过ADC测量这个电压值,发生800-1500HZ频率的,就是不知道PID算法执行OUT参数怎么设置?
2、我在网上找到一个别人程序中 if(pp->SumError>900)  pp->SumError=900;
     else if(pp->SumError<-900)   pp->SumError=-900;这几句什么用处,看到不少很明白,为什么要加这几句话,我很好奇,为什么他的算法没有积分时间,微分时间?感觉这个程序经典的。PID这三个参数怎么处理。
//*====================================================================================================
PID Function
The PID (比例、积分、微分) function is used in mainly
control applications. PIDCalc performs one iteration of the PID
algorithm.
While the PID function works, main is just a dummy program showing
a typical usage.
=====================================================================================================*/
typedef struct PID {
float SetPoint; // 设定目标Desired value
float Proportion; // 比例常数Proportional Const
float Integral; // 积分常数Integral Const
float Derivative; // 微分常数Derivative Const
float LastError; // Error[-1]
float PrevError; // Error[-2]
float SumError; // Sums of Errors
} PID;
/*====================================================================================================/
PID计算部分
=====================================================================================================*/
PID   vPID={0,0.1,0.001,0.001,0,0,0};
float PIDCalc( PID *pp, float NextPoint )
{
float dError,
Error;
Error = pp->SetPoint - NextPoint; // 偏差
pp->SumError += Error; // 积分
dError = pp->LastError - pp->revError; // 当前微分
pp->revError = pp->LastError;
pp->LastError = Error;
    if(pp->SumError>900)  pp->SumError=900;
    else if(pp->SumError<-900)   pp->SumError=-900;
return (pp->roportion * Error // 比例项
+ pp->Integral * pp->SumError // 积分项
+ pp->Derivative * dError // 微分项
);
}
float Vol(int vSet,int v3){
float vOut; // PID Response (Output)
float vIn; // PID Feedback (Input)
vPID.SetPoint = vSet; // Set PID Setpoint
vIn = (float)v3; // Read Input
vOut = PIDCalc ( &vPID,vIn ); // Perform PID Interation  
return vOut;
}
void mian()
{
while(1)
{
if(Flag_3S==1)
  {
   if(target-TIM_ExtCntFreq>=6||target-TIM_ExtCntFreq<=-6)
   {
        Pv=Vol(target,TIM_ExtCntFreq);// PID算法
        dac_value=dac_value+Pv/2.04;//DAC 寄存器调节
    DAC_SetChannel1Data(DAC_Align_12b_R,dac_value);
   }
   led3=~led3;
   Flag_3S=0;
}
   
  }
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

51

主题

2166

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10653
金钱
10653
注册时间
2017-4-14
在线时间
2780 小时
发表于 2019-9-2 12:59:38 | 显示全部楼层
900 是抗饱和 假如改成9000 开始反向的时候要多经理9000-900的时间 一般这个是不能接受的,所以设置各最大积分饱和深度,这样反向响应快       固定时间间隔调用pid就不需要周期频率了,等于是个常数
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-11 11:33

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表