📄 pid.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 + -