ECOOK 发表于 2009-12-7 10:36:29

充电器中的PID的源码有些不懂,请大家帮忙看一下。

头文件:


#ifndef        __PID__H
#define        __PID__H


#define SCALING_FACTOR128

typedef struct PID_DATA{
//! Last process value, used to find derivative of process value.
int16_t lastProcessValue;
//! Summation of errors, used for integrate calculations
int32_t sumError;
//! The Proportional tuning constant, multiplied with SCALING_FACTOR
int16_t P_Factor;
//! The Integral tuning constant, multiplied with SCALING_FACTOR
int16_t I_Factor;
//! The Derivative tuning constant, multiplied with SCALING_FACTOR
int16_t D_Factor;
//! Maximum allowed error, avoid overflow
int16_t maxError;
//! Maximum allowed sumerror, avoid overflow
int32_t maxSumError;
} pidData_t;
*
* Needed to avoid sign/overflow problems
*/
// Maximum value of variables
#define MAX_INT         0x011F            //INT16_MAX
#define MAX_LONG      INT32_MAX
#define MAX_I_TERM      (INT32_MAX / 2)

// Boolean values
#define FALSE         0
#define TRUE            1
#endif


源文件:


void pid_Init(signed int p_factor, signed int i_factor, signed int d_factor, struct PID_DATA *pid)
{
    // Start values for PID controller
   
    pid->sumError = 0;
    pid->lastProcessValue = 0;
   
    // Tuning constants for PID loop
    pid->P_Factor = p_factor;
    pid->I_Factor = i_factor;
    pid->D_Factor = d_factor;
   
    // Limits to avoid overflow
    pid->maxError = MAX_INT / (pid->P_Factor + 1);
    pid->maxSumError = MAX_I_TERM / (pid->I_Factor + 1.0); //sea
}

/*******************************************************************************************************
** 函数名称: pid_Controller
** 功能描述: Calculates output from setpoint, process value and PID status.
** 输入参数: int16_t setPoint: Desired value.
**         int16_t processValue: Measured value.
**         struct PID_DATA *pid_st: PID status struct.
** 输出参数: 无
********************************************************************************************************/
int16_t pid_Controller(int16_t setPoint, int16_t processValue, struct PID_DATA *pid_st)
{
    int16_t error, p_term, d_term;
    int32_t i_term, ret, temp;

   
    error = setPoint - processValue;
   

    if (error > pid_st->maxError)      // Calculate Pterm and limit error overflow
    {
      p_term = MAX_INT;
    }
    else if (error < -pid_st->maxError)
    {
      p_term = -MAX_INT;
    }
    else
    {
      p_term = pid_st->P_Factor * error;
    }
   
      
   
    temp = pid_st->sumError + error;   // Calculate Iterm and limit integral runaway
    if(temp > pid_st->maxSumError)
    {
      i_term = MAX_I_TERM;
      pid_st->sumError = pid_st->maxSumError;
    }
    else if(temp < -pid_st->maxSumError)
    {
      i_term = -MAX_I_TERM;
      pid_st->sumError = -pid_st->maxSumError;
    }
    else
    {
      pid_st->sumError = temp;
      i_term = pid_st->I_Factor * pid_st->sumError;
    }
   
   
    d_term = pid_st->D_Factor * (pid_st->lastProcessValue - processValue);// Calculate Dterm
   
    pid_st->lastProcessValue = processValue;

    ret = (p_term + i_term + d_term) / SCALING_FACTOR;
    if(ret > MAX_INT)
    {
      ret = MAX_INT;
    }
    else if(ret < -MAX_INT)
    {
      ret = -MAX_INT;
    }
   
    //lcd_locate(5,1);
    //lcd_print_number(ret,4,0);   
   
    return((int16_t)ret);
}


1、在这里,MAX_I_TERM定义为INT32_MAX/2,为什么要除以2呢?
2、PID初始化的时候   
    pid->maxError = MAX_INT / (pid->P_Factor + 1);
    pid->maxSumError = MAX_I_TERM / (pid->I_Factor + 1.0); //sea
这里分母加1和1.0是什么意思?
3、如果用这个PID算法控制电压和电流,控制对象不同不会有什么问题吗?比如说对锂电池充电,要求恒压4.2V,会不会控制使得电压为4.2V的同时,电流太大了呢?或者恒流充电的时候,控制在保持恒定电流的同时,电压却会超过4.2V呢?能同时兼顾吗?
4、PID的参数P,I,D该如何确定呢?我看到充电器源码上给出的是P=5.4,I=0.01,D=0。

初次用PID,请大家帮忙,没说清楚的地方,请大家指出。谢谢了

ysoni 发表于 2009-12-7 11:13:58

可不可以把完整的代码发一份来研究

ECOOK 发表于 2009-12-8 15:35:33

回LS:
代码在这http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=937085&bbs_page_no=1&bbs_id=1026

xxq123 发表于 2010-1-11 10:09:28

正在看这段代码,顶上去!

xxq123 发表于 2010-1-13 10:13:27

存在同样疑问!

ltby00 发表于 2010-5-25 15:44:52

知道的兄弟可否解释一下???
   还有 #define SCALING_FACTOR128    是做什么用的呢 ?

wqx0532 发表于 2010-5-25 23:12:47

没人来解释啊

coolwater 发表于 2010-6-30 14:54:10

mark
页: [1]
查看完整版本: 充电器中的PID的源码有些不懂,请大家帮忙看一下。