赞
踩
一、自定义PID结构体
- //首先定义PID结构体用于存放一个PID的数据
- typedef struct
- {
- float kp,ki,kd;//三个系数
- float error,lastError;//误差、上次误差
- float integral,maxIntegral;//积分、积分限幅
- float output,maxOutput;//输出、输出限幅
- }PID
-
- //用于初始化pid参数的函数
- void PID_Init(PID *pid,float p,float i,float d,float maxI,float maxOut)
- {
- pid->kp=p;
- pid->ki=i;
- pid->kd=d;
- pid->maxIntegral=maxI;
- pid->maxOutput=maxOut;
- }
二、进行PID计算
- //进行一次pid计算
- //参数为(pid结构体,目标值,反馈值),计算结果放在pid结构体的output成员中
- void PID_Calc(PID *pid,float reference,float feedback)
- {
- //更新数据
- pid->lastError=pid->error;//将旧error存起来
- pid->error=reference-feedback;//计算新error
- //计算微分
- float dout=(pid->error-pid->lastError)*pid->kd;
- //计算比例
- float pout=pid->error*pid->kp;
- //计算积分
- pid->integral+=pid->error*pid->ki;
- //积分限幅
- if(pid->integral > pid->maxIntegral) pid->integral=pid->maxIntegral;
- else if(pid->integral < -pid->maxIntegral) pid->integral=-pid->maxIntegral;
- //计算输出
- pid->output=pout+dout+pid->integral;
- //输出限幅
- if(pid->output > pid->maxOutput) pid->output=pid->maxOutput;
- else if(pid->output <-pid->maxOutput) pid->output=-pid->maxOutput;
- }
三、周期调用PID计算
- void TIM2_IRQHandler(void) //
- {
- if(TIM_GetITStatus(TIM2,TIM_IT_Update))
- {
- /*读取编码器测量的速度值*/
- gspeed=Read_EncoderB()*60/(SampleCircle_100*0.01*4*50);
- /*周期调用PID计算,得到PWM输出值*/
- PID_Calc(&mypid,TargetVelocity,gspeed);
- /*根据PWM值控制电机转动*/
- carry_pid(mypid.output);
- }
- TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。