166 lines
4.5 KiB
C
Raw Normal View History

2024-05-13 08:14:17 +08:00
/*
* Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD
* All rights reserved.
*
* Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use
* exclusively with CVA's microcontroller products. This file can be freely
* distributed within development tools that are supporting such microcontroller
* products.
*
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
* OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*/
#ifndef _PID_H_
#define _PID_H_
/*! \brief Contains public interface to various functions related
* to the PID object.
* \note The form of this PID is parallel.
*/
/*******************************************************************************
* the includes
******************************************************************************/
#include "common/iqmath/iqmath.h"
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* the defines
******************************************************************************/
/*******************************************************************************
* the typedefs
******************************************************************************/
/*! \brief Declaration of PID object
*/
typedef struct _PidType_
{
_iq ref; /*!< Input: Reference input */
_iq fdb; /*!< Input: Feedback input */
_iq Kp; /*!< Parameter: Proportional gain */
_iq Ki; /*!< Parameter: Integral gain */
_iq Kd; /*!< Parameter: Derivative gain */
_iq outMax; /*!< Parameter: Maximum output */
_iq outMin; /*!< Parameter: Minimum output */
_iq Ui; /*!< Internal Variable: Integral output */
_iq lastError; /*!< Internal Variable: last error */
_iq output; /*!< Output: PID output */
} PidType;
/*******************************************************************************
* the globals
******************************************************************************/
/*******************************************************************************
* the function prototypes
******************************************************************************/
/*! \brief Initialize the PID object
*
* This function initializes the PID instance
*
* \param[in] obj : pointer to Pid instance
* \param[in] Kp : the Kp value in IQ format
* \param[in] Ki : the Ki value in IQ format
* \param[in] Kd : the Kd value in IQ format
* \param[in] min : the min value allowed in output
* \param[in] max : the max value allowed in output
*/
static inline void Pid_Init(PidType *obj, _iq Kp, _iq Ki, _iq Kd, _iq min, _iq max)
{
obj->Kp = Kp;
obj->Ki = Ki;
obj->Kd = Kd;
obj->outMin = min;
obj->outMax = max;
obj->ref = 0;
obj->fdb = 0;
obj->Ui = 0;
obj->lastError = 0;
obj->output = 0;
}
/*! \brief Run the PID control
*
* This fucntion runs the PID control
*
* \note The form of this PID is parallel
*
* \param[in] obj : pointer to Pid instance
*/
static inline void Pid_Run(PidType *obj)
{
/* Compute the error */
_iq error = obj->ref - obj->fdb;
/* Compute the proportional output */
_iq Up = _IQmpy(obj->Kp, error);
/* Compute the integral output */
obj->Ui = obj->Ui + _IQmpy(obj->Ki, error);
/* Saturate Ui */
if(obj->Ui > obj->outMax)
{
obj->Ui = obj->outMax;
}
if(obj->Ui < obj->outMin)
{
obj->Ui = obj->outMin;
}
/* Compute the derivative output */
_iq Ud = _IQmpy(obj->Kd, (error - obj->lastError));
obj->lastError = error;
/* Compute the pre-saturated output */
_iq tmpOutput = Up + obj->Ui + Ud;
/* Saturate the output */
if(tmpOutput > obj->outMax)
{
obj->output = obj->outMax;
}
else if(tmpOutput < obj->outMin)
{
obj->output = obj->outMin;
}
else
{
obj->output = tmpOutput;
}
}
/*! \brief Reset the PID variables
*
* This function reset the PID to initial state
*
* \note The form of this PID is parallel
*
* \param[in] obj : pointer to Pid instance
*/
static inline void Pid_Reset(PidType *obj)
{
obj->lastError = 0;
obj->output = 0;
obj->Ui = 0;
}
#ifdef __cplusplus
}
#endif /* extern "C" */
#endif /* _PID_H_ */