⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 v_pid.h

📁 使用ICCAVR编辑
💻 H
字号:
/***************************PID算法有关**********************************************/
/**************************定义PID的三个参数*************************/
#define VV_KAVALUE  0x30
#define VV_KBVALUE  0x10
#define VV_KCVALUE  0x10
// Ka, Kc偏大, 从10以内开始较好

/******************************************************************************
设置相应的PID常量:
控制死区;上下限;
*******************************************************************************/


typedef	struct 	//定义运算数据
{
	signed int vi_Ref;		  	 //速度PID,速度设定值
	signed int vi_FeedBack;		 //速度PID,速度反馈值
	
	signed int vi_PreError;	  	//速度PID,前一次,速度误差, vi_Ref - vi_FeedBack
	signed int vi_PreDerror;	//速度PID,前一次,速度误差之差, d_error - PreDerror ;
	
	signed int v_Ka;			//速度PID,Ka = Kp
	signed int v_Kb;			//速度PID,Kb = ( T / Ti )
	signed int v_Kc;			//速度PID,kc =  ( Td / T )
	
	signed long vi_PreU;		//电机控制输出值
		
} PID;
PID	 sPID;        		//  PID Control Structure		


/**********************************************************************
PID参数初始化
**********************************************************************/
void PIDInit ()
{	
	sPID.vi_Ref = 0 ;			//速度设定值
	sPID.vi_FeedBack = 0 ;		//速度反馈值
	
	sPID.vi_PreError = 0 ;	  	//前一次,速度误差,,vi_Ref - vi_FeedBack
	sPID.vi_PreDerror = 0 ;		//前一次,速度误差之差,PreDerror - d_error
	
	sPID.v_Ka = VV_KAVALUE;
	sPID.v_Kb = VV_KBVALUE;
	sPID.v_Kc = VV_KCVALUE;
	
	sPID.vi_PreU = 0 ;		//电机控制输出值
}


/**********************************************************************
简单PID算法
**********************************************************************/
signed int v_PIDCalc( PID *pp )
{

	  int ek, d_error;
	  unsigned char beta;

	  ek = pp->vi_Ref - pp->vi_FeedBack;				// 本次速度误差

	  // 遇限削弱积分法,如果进入饱和区,并且积分增加,则不进行积分运算,尽快离开饱和。
	  // 用beta作为积分运算与否的标志
	  if  ( ( pp->vi_PreU >=540 && ek>0 ) || ( pp->vi_PreU <= 0 && ek<0 ) )
		     beta=0;
	  else beta = 1;
		
	  d_error = ek - pp->vi_PreError;							// 本次速度误差与前次误差之差
	  pp->vi_PreDerror = d_error - pp->vi_PreDerror;		// 更新前一次速度误差之差

	  // 增量式PID控制, 更新电机控制输出值
	  pp->vi_PreU+= ( pp->v_Ka *  ( d_error +  beta * pp->v_Kb * ek + pp->v_Kc * pp->vi_PreDerror ) ) >>5;	
		// 增量的范围(0~30*(1+10+10)*256=161280)转换为(0~550),需要尝试改变移位数, 在4~7之间效果好

	  pp->vi_PreError = ek;													// 更新前一次速度误差
		
	  // 处理饱和效应
	  if ( pp->vi_PreU >550 ) 
		  pp->vi_PreU = 550;
	  else if ( pp->vi_PreU <0 )
	     pp->vi_PreU = 0;

     return      ( pp->vi_PreU );

//return 	((sPID.vi_Ref << 1)+ 50 );  // 开环返回值
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -