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

📄 pid.c

📁 基于STM32的双极性逆变器软件
💻 C
字号:
#include "stm32f10x_lib.h"
#include "stm32f10x_it.h"
#include "PWM_adjust.h"
#include "bitdef.h"


extern u16 v1;//I1->总;v6->太阳能;v4->风能  I1=v6+v4  v6 for solar pi	  ;v1->V总output
//v3额定量为70A(7000);v6额定量为30A(3000); v1额定量为54V(5400)		过充电压为56v(5600);充满电压为54.8v(5480)
extern u32 SRC_Buffer;
extern u32 SRC_Buffer1;

 u16 pwm1=0;	 //5760 max	 80%pwm
 u16 pwm2=0;	 //2880 max	 80%pwm
u8 deadtime=0;  //204max  80%pwm
u16 pwm_all=0;		   // 11518 max
//***********************设定值**********************************************
u16 set_I1=3000,set_I2=7000,set_v1=5480;
//**********************切换标志*********************************************
u8 chang_flag=0;	 //>53->0;>56->1
//*************************PID变量定义***************************************
float kp1=0.008;	   //PID调节的比例常数	  0.04
float ki1=0.005;	   //PID调节的积分常数	  0.02
float kd1=0;//0.0001;	   //PID调节的微分时间常数	0.04

float kp2=0.006;	   //PID调节的比例常数	  0.04
float ki2=0.002;	   //PID调节的积分常数	  0.02
float kd2=0;//0.00005;	   //PID调节的微分时间常数	0.04
//extern int fi;

float kp3=0.001;	   //PID调节的比例常数	  0.04
float ki3=0.0004;	   //PID调节的积分常数	  0.02
float kd3=0;//0.0001;	   //PID调节的微分时间常数	0.04



//**************************定义PID变量****************************************
struct PID_Data
{
   struct
   {
	  int y;    //实际测量值
	} signals;
	struct
	{
	  int angle;   //实际控制器输出值
	  int deta_angle;
	  int angle_1;    //u[(k-1)t]
	  int angle_2;    //u[(k-2)t]
	  int y_1;    //y[(k-1)t]
	  int y_2;    //y[(k-2)t]
	  int error0;
	  int error_1;
	  int error_2;
	 // float kp;	   //PID调节的比例常数
	 // float ki;	   //PID调节的积分常数
	 // float kd;	   //PID调节的微分时间常数
	}states;
	struct
	{
	   float x1;
	   float x2;
	   float x3;	
	} par;
  }pid_data,pid_data1,pid_data2;  

  

 /*******************************************************************************
* 函数名  : PID_Init
* 描述    : 该函数用于PID参数初始化         
* 输入    : struct PID_Data*data
* 输出    : 无
* 返回    : 无
*******************************************************************************/
void PID_Init(struct PID_Data*data)
{
  
  data->states.deta_angle=0;
  data->states.angle_1=0;
  data->states.angle_2=0;
  data->states.y_1=0;
  data->states.y_2=0;
  data->states.error_1=0;
  data->states.error_2=0;
  data->par.x1=0;
  data->par.x2=0;
  data->par.x3=0;
}


/*******************************************************************************
* 函数名  : pid_I1
* 描述    : 该函数用于计算风能控制器PWM         
* 输入    : struct PID_Data*data
* 输出    : 调整量out
* 返回    : out
*******************************************************************************/
 void pid_I1(struct PID_Data*data,u16 uc)	   //设定值,默认为30A(3000)
 {
    data->signals.y=v4;   //要实际改
	data->states.error0=uc-data->signals.y;  //09.8.19日修改
	//.......控制器输出增量值............
	//***************************特殊改进,如果大于300V,P小,如果小于300V,P大*********
	//if(data->states.error0<=0) {
	data->states.deta_angle=kp1*data->par.x1+ki1*data->par.x2+kd1*data->par.x3;//}
    //if(data->states.error0>0){data->states.deta_angle=0.25*data->par.x1+ki*data->par.x2+0.1*data->par.x3;}
	//.......计算控制器输出..............

	data->states.angle=data->states.angle_1+data->states.deta_angle;
	
	//.......判断实际控制器输出..........
	
	if(data->states.angle>=7199)   //要实际改 5759
	 {
	   data->states.angle=7199;
	 }
	 else if(data->states.angle<=0)   //要实际改
	 {
	   data->states.angle=0;
	 }
	 else 
	 {
	   data->states.angle=data->states.angle;
	 }
	 pwm1=data->states.angle;
	//data->states.error0=data->signals.uc-data->signals.y;  //09.8.19修改
	 data->states.angle_2=data->states.angle_1;  //更新状态变量
	 data->states.angle_1=data->states.angle;
	 data->states.y_2=data->states.y_1;
	 data->states.y_1=data->signals.y;
	 data->par.x1=data->states.error0-data->states.error_1;//计算中间变量
	 data->par.x3=data->states.error0-2*data->states.error_1+data->states.error_2;
	 data->par.x2=data->states.error0;
	 data->states.error_2=data->states.error_1;	   //更新状态变量
	 data->states.error_1=data->states.error0;
 	 
 }

 /*******************************************************************************
* 函数名  : pid_I2
* 描述    : 该函数用于计算太阳能死区         
* 输入    : struct PID_Data*data
* 输出    : 调整量out
* 返回    : out
*******************************************************************************/
 void pid_I2(struct PID_Data*data,u16 uc)	   //设定值,默认为30A(3000)
 {
    data->signals.y=v6;   //要实际改
	data->states.error0=uc-data->signals.y;  //09.8.19日修改
	//.......控制器输出增量值............
	//***************************特殊改进,如果大于300V,P小,如果小于300V,P大*********
	//if(data->states.error0<=0) {
	data->states.deta_angle=kp2*data->par.x1+ki2*data->par.x2+kd2*data->par.x3;//}
    //if(data->states.error0>0){data->states.deta_angle=0.25*data->par.x1+ki*data->par.x2+0.1*data->par.x3;}
	//.......计算控制器输出..............
	data->states.angle=data->states.angle_1+data->states.deta_angle;
	//.......判断实际控制器输出..........
	if(data->states.angle>=7199)   //要实际改
	 {
	   data->states.angle=7199;
	 }
	 else if(data->states.angle<=0)   //要实际改
	 {
	   data->states.angle=0;
	 }
	 else 
	 {
	   data->states.angle=data->states.angle;
	 }
	 pwm2=data->states.angle;
	//data->states.error0=data->signals.uc-data->signals.y;  //09.8.19修改
	 data->states.angle_2=data->states.angle_1;  //更新状态变量
	 data->states.angle_1=data->states.angle;
	 data->states.y_2=data->states.y_1;
	 data->states.y_1=data->signals.y;
	 data->par.x1=data->states.error0-data->states.error_1;//计算中间变量
	 data->par.x3=data->states.error0-2*data->states.error_1+data->states.error_2;
	 data->par.x2=data->states.error0;
	 data->states.error_2=data->states.error_1;	   //更新状态变量
	 data->states.error_1=data->states.error0;
 	 
 }


 /*******************************************************************************
* 函数名  : pid_v1
* 描述    : 该函数用于计算v->I        
* 输入    : struct PID_Data*data
* 输出    : 调整量out
* 返回    : out
*******************************************************************************/
 void pid_v1(struct PID_Data*data,u16 uc)	   //设定值,默认为30A(3000)
 {
    data->signals.y=v1;   //要实际改
	data->states.error0=uc-data->signals.y;  //09.8.19日修改
	//.......控制器输出增量值............
	//***************************特殊改进,如果大于300V,P小,如果小于300V,P大*********
	//if(data->states.error0<=0) {
	data->states.deta_angle=kp3*data->par.x1+ki3*data->par.x2+kd3*data->par.x3;//}
    //if(data->states.error0>0){data->states.deta_angle=0.25*data->par.x1+ki*data->par.x2+0.1*data->par.x3;}
	//.......计算控制器输出..............
	data->states.angle=data->states.angle_1+data->states.deta_angle;
	
	//.......判断实际控制器输出..........
	if(data->states.angle>=11520)   //要实际改
	 {
	   data->states.angle=11520;
	 }
	 else if(data->states.angle<=0)   //要实际改
	 {
	   data->states.angle=0;
	 }
	 else 
	 {
	   data->states.angle=data->states.angle;
	 }
	 pwm_all=data->states.angle;
	//data->states.error0=data->signals.uc-data->signals.y;  //09.8.19修改
	 data->states.angle_2=data->states.angle_1;  //更新状态变量
	 data->states.angle_1=data->states.angle;
	 data->states.y_2=data->states.y_1;
	 data->states.y_1=data->signals.y;
	 data->par.x1=data->states.error0-data->states.error_1;//计算中间变量
	 data->par.x3=data->states.error0-2*data->states.error_1+data->states.error_2;
	 data->par.x2=data->states.error0;
	 data->states.error_2=data->states.error_1;	   //更新状态变量
	 data->states.error_1=data->states.error0;
 	 
 }


 void pid_int_tw(void)
 {
     PID_Init(&pid_data);//PID初始化
	 PID_Init(&pid_data1);
	 PID_Init(&pid_data2);
 }
 
void Adjust(void){ 
  if(v1>5600) chang_flag=1;
  else if(v1<5300) chang_flag=0;
  if(!chang_flag){
  //----------------------------------
   //POUTB4=0;
  // POUTB5=1;
   pid_I1(&pid_data,set_I1);
   pid_I2(&pid_data1,set_I2);
    }
  else{
  //-----------------------------
     //POUTB4=1;
	 //POUTB5=0;
     if(v1>5500)  {pwm1=0; pwm2=0;}
	 else{
        pid_v1(&pid_data2,set_v1);
 	    pwm1=(int)((float)pwm_all*0.67);
	    pwm2=(unsigned char)((float)pwm_all*0.33);	 }
    }
  
 // PWM1(3000);	//	pwm1
 // PWM2(255);	  // deadtime
  	if(pwm1<=5) pwm1=0;
	if(pwm2<=5) pwm2=0;

    SRC_Buffer1=pwm1;

  SRC_Buffer=pwm2;
  //SRC_Buffer[1]=pwm2;
  PWM_DMA_Configuration(); 
}

⌨️ 快捷键说明

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