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

📄 pid.c

📁 电机PID调速程序
💻 C
字号:
#include <ADUC842.H>
#include <math.h>
#include "feedback.h"
#include "PID.h"
#include"lcd.h"

#define  VMAX  250					//最大速度

#define  BACKWARD_L		1					//定义前进为一					
#define  FORWARD_L  	0				
#define  BACKWARD_R  	0
#define  FORWARD_R		1

sbit DIR_R = P0^1;
sbit DIR_L = P0^3;

/*************速度PID相关参数定义*******************/
float xdata V_Kp;					//V_PID参数
float xdata V_Ki;

int xdata e_V_L;				//速度反馈PID变量ei
int xdata e1_V_L;				//e(i-1)
int xdata e_V_R;
int xdata e1_V_R;

float xdata d_u_V_L;			//速度PID u的增量
float xdata d_u_V_R;

float xdata tem_data;		   //中间变量,用于解决中断中表达式过长引起的得数错误问题

int xdata beta_V_L;
int xdata beta_V_R;

int interval_V;     // 速度间隔
char dis_V;         // 允许速度误差

int tem_V_L;	    //暂时目标速度
int tem_V_R;

int aim_V_R;	    //最终目标速度,全局变量
int aim_V_L;
/*************速度PID相关参数定义*******************/ 

float xdata u_L;              //占空比
float xdata u_R;

//------------------------------超级PID函数---------------------------------------
//函数名:MOTOR_PID
//参数:(左轮目标速度、右轮目标速度)
//说明:采用遇限削弱积分PID控制算法,目标速度和加速度值是与实际速度和电流成比例的值,各个值的上限要根据不同的电机实验测量
void MOTOR_V_PID(void)
{	 
	
   //为了减少电机在饱和区停留过久,设置参数beta_lbe,y当进入饱和区,不计算积分值
	  if(u_L>VMAX||u_L<(0-VMAX))				
	  {
		beta_V_L = 0;
	  }
      else
	  {
	 	beta_V_L = 1;
	  }
	  if(u_R>VMAX||u_R<(0-VMAX))
	  {
		beta_V_R = 0;
      }
	  else
	  {
		beta_V_R = 1;
	  }
	
	//---------------------增量型V-PID计算-----------------------------
		e_V_L = (tem_V_L - fb_V_L);
		tem_data = V_Ki * beta_V_L;// 由于按二阶工程算法计算, 微分相为零,故略去微分相
		tem_data =	tem_data * e_V_L;
		d_u_V_L = tem_data;
		tem_data = V_Kp * (e_V_L - e1_V_L);
		d_u_V_L = tem_data+d_u_V_L;
		u_L += d_u_V_L;
	//---------------------增量型V-PID计算-----------------------------
		e_V_R = (tem_V_R - fb_V_R);
		tem_data = V_Ki * beta_V_R;
		tem_data =	tem_data * e_V_R;
		d_u_V_R = tem_data;
		tem_data = V_Kp * (e_V_R - e1_V_R);
		d_u_V_R = tem_data+d_u_V_R;
		u_R += d_u_V_R;
	
	//----------左轮输出电压限制--选择VMAX的值时要防止溢出-------------
		if(u_L>VMAX)						         
		{
			u_L = VMAX;
		}
		if(u_L<(0-VMAX))
		{
			u_L = 0 - VMAX;
		}
	//----------右轮输出电压限制-------------------
		if(u_R>VMAX)
		{
			u_R= VMAX;
		}
		if(u_R<(0-VMAX))
		{
			u_R = 0 - VMAX;
		}
		putstr("u_L",1);
		putnum(u_L);
		putstr("u_R",2);
		putnum(u_R);
		
	//--------配置电机输出方向---------------------
		
		if(u_R<0)
		{
			DIR_R = BACKWARD_R;			       //这里还要重新分析 主要是因为不知道车怎样是前走,怎样后走
			PWM0L = 0 - u_R;				       
		}
		else
		{
			DIR_R = FORWARD_R;
			PWM0L = u_R;						   //pwm寄存器能是浮点数么?//不能,浮点数会被转换位整型
		}
		
		if(u_L<0)
		{
			DIR_L = BACKWARD_L;
			PWM0H = 0 - u_L;					   //此处其实也是一个将u_L的绝对值传给PWM0L的过程
		}									       //这样处理可以不调用fabs()函数,可能速度更快
		else
		{
			DIR_L = FORWARD_L;	
			PWM0H = u_L;
		}
	//----------保存部分信息,以备下次计算使用---------------------------
		e1_V_L = e_V_L;								//注意传递顺序
		e1_V_R = e_V_R;
}






⌨️ 快捷键说明

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