update_PID2PID-位置式

#ifndef __BSP_PID_H
#define __BSP_PID_H

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

typedef struct
{
    float target_val;   //目标值
    float err;          //偏差值
    float err_last;     //上一个偏差值
    float Kp, Ki, Kd;   //比例、积分、微分系数
    float integral;     //积分值
    float output_val;   //输出值
} PID;

extern PID pid_Temper;
extern PID pid_speed;

void  PID_param_init(void);
void  set_pid_target(PID *pid, float temp_val);
float get_pid_target(PID *pid);
void  set_p_i_d(PID *pid, float p, float i, float d);
float Temper_pid_update(PID *pid, float actual_val);
float speed_pid_update(PID *pid, float actual_val);

#endif
#include "bsp_pid.h"


/*定义位置PID与速度PID结构体型的全局变量*/
PID pid_Temper;
PID pid_speed;

/**
  * @brief  PID参数初始化
  * @note   无
  * @retval 无
  */
void PID_param_init()
{

    /* 位置相关初始化参数 */
    pid_Temper.target_val = 0;
    pid_Temper.output_val = 0.0;
    pid_Temper.err = 0.0;
    pid_Temper.err_last = 0.0;
    pid_Temper.integral = 0.0;

    pid_Temper.Kp = 3;
    pid_Temper.Ki = 0.2;
    pid_Temper.Kd = 5;

    /* 速度相关初始化参数 */
    pid_speed.target_val = 10.0;
    pid_speed.output_val = 0.0;
    pid_speed.err = 0.0;
    pid_speed.err_last = 0.0;
    pid_speed.integral = 0.0;

    pid_speed.Kp = 3.65;
    pid_speed.Ki = 0.007;
    pid_speed.Kd = 300.0;

}

extern float det_plus;
/**
  * @brief  设置目标值
  * @param  val     目标值
  * @note   无
  * @retval 无
  */
void set_pid_target(PID *pid, float temp_val)
{
    pid->target_val = temp_val;    // 设置当前的目标值
}

/**
  * @brief  获取目标值
  * @param  无
  * @note   无
  * @retval 目标值
  */
float get_pid_target(PID *pid)
{
    return pid->target_val;    // 获取当前的目标值
}


/**
  * @brief  设置比例、积分、微分系数
  * @param  p:比例系数 P
  * @param  i:积分系数 i
  * @param  d:微分系数 d
  * @note   无
  * @retval 无
  */
void set_p_i_d(PID *pid, float p, float i, float d)
{
    pid->Kp = p;    // 设置比例系数 P
    pid->Ki = i;    // 设置积分系数 I
    pid->Kd = d;    // 设置微分系数 D
}




/**
  * @brief  位置PID算法实现
  * @param  actual_val:实际值
  * @note   无
  * @retval 通过PID计算后的输出
  */
#define TEMPER_DEAD_ZONE 60 /*位置环死区*/
#define TEMPER_INTEGRAL_START_ERR 50 /*积分分离时对应的误差范围*/
#define TEMPER_INTEGRAL_MAX_VAL 150   /*积分范围限定,防止积分饱和*/
float Temper_pid_update(PID *pid, float actual_val)
{
    /*计算目标值与实际值的误差*/
    pid->err = pid->target_val - actual_val;

    #if 0
    /* 设定闭环死区 */
    if ((pid->err >= -TEMPER_DEAD_ZONE) && (pid->err <= TEMPER_DEAD_ZONE))
    {
        pid->err = 0;
        pid->integral = 0;
        pid->err_last = 0;
    }
    #endif

    #if 0
    /*积分项*/
    pid->integral += pid->err;
    #else
    /*积分项,积分分离,偏差较大时去掉积分作用*/
    if (pid->err > -TEMPER_INTEGRAL_START_ERR && pid->err < TEMPER_INTEGRAL_START_ERR)
    {
        pid->integral += pid->err;
        /*积分范围限定,防止积分饱和*/
        if (pid->integral > TEMPER_INTEGRAL_MAX_VAL)
        {
            pid->integral = TEMPER_INTEGRAL_MAX_VAL;
        }
        else if (pid->integral < -TEMPER_INTEGRAL_MAX_VAL)
        {
            pid->integral = -TEMPER_INTEGRAL_MAX_VAL;
        }
    }
    #endif

    /*PID算法实现*/
    pid->output_val = pid->Kp * pid->err +
                      pid->Ki * pid->integral +
                      pid->Kd * (pid->err - pid->err_last);

    /*误差传递*/
    pid->err_last = pid->err;

    /*返回当前实际值*/
    return pid->output_val;
}

/**
  * @brief  速度PID算法实现
  * @param  actual_val:实际值
  * @note   无
  * @retval 通过PID计算后的输出
  */
#define SPE_DEAD_ZONE 5.0f /*速度环死区*/
#define SPE_INTEGRAL_START_ERR 300 /*积分分离时对应的误差范围*/
#define SPE_INTEGRAL_MAX_VAL 150   /*积分范围限定,防止积分饱和*/
float speed_pid_update(PID *pid, float actual_val)
{
    /*计算目标值与实际值的误差*/
    pid->err = pid->target_val - actual_val;

    #if 0
    /* 设定闭环死区 */
    if ((pid->err > -SPE_DEAD_ZONE) && (pid->err < SPE_DEAD_ZONE))
    {
        pid->err = 0;
        pid->integral = 0;
        pid->err_last = 0;
    }
    #endif

    #if 0
    /*积分项*/
    pid->integral += pid->err;
    #else
    /*积分项,积分分离,偏差较大时去掉积分作用*/
    //if (pid->err > -SPE_INTEGRAL_START_ERR && pid->err < SPE_INTEGRAL_START_ERR)
    {
        pid->integral += pid->err;
        /*积分范围限定,防止积分饱和*/
        if (pid->integral > SPE_INTEGRAL_MAX_VAL)
        {
            pid->integral = SPE_INTEGRAL_MAX_VAL;
        }
        else if (pid->integral < -SPE_INTEGRAL_MAX_VAL)
        {
            pid->integral = -SPE_INTEGRAL_MAX_VAL;
        }
    }
    #endif

    /*PID算法实现*/
    pid->output_val = pid->Kp * pid->err +
                      pid->Ki * pid->integral +
                      pid->Kd * (pid->err - pid->err_last);

    /*误差传递*/
    pid->err_last = pid->err;

    /*返回当前实际值*/
    return pid->output_val;
}
#include "het_config.h"
extern PID pid_Temper;
extern PID pid_speed;
extern sturheat stheat;


void update_PID2PID(void)
{
    static char step = 0;
    static short ticks = 0;

    static short temperLast = 0;
    static short temperDelta = 0;

    if (step == 0)
    {
        step = 1;
        PID_param_init();   // 初始化PID控制器
    }


    if ((ticks++ % 4) == 0)
    {
        // 设置外环设定值
        set_pid_target(&pid_Temper, stheat.setTemp);

        //位置PID计算
        Temper_pid_update(&pid_Temper, stheat.temperature);

        temperDelta = stheat.temperature - temperLast; /*得到变化值*/
        temperLast =  stheat.temperature;/*更新上次的累计值*/

    }

    //设定速度PID的目标值
    set_pid_target(&pid_speed, pid_Temper.output_val);

    gHeat.Scr_Duty = speed_pid_update(&pid_speed, temperDelta);
    if (pid_Temper.target_val == 0)   // 设定的温度设定值为0时,将输出值设置为0
    {
        gHeat.Scr_Duty = 0;
    }

    if (gHeat.Scr_Duty < 0)   // 对输出值进行限制,确保在合理范围内
    {
        gHeat.Scr_Duty = 0;
    }
    else if (gHeat.Scr_Duty > 1000)
    {
        gHeat.Scr_Duty = 1000;
    }


}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值