增量式PID C语言
已有 2546 次阅读2011-11-24 20:37
|系统分类:嵌入式系统|
增量式PID
最近在解决激光器恒功率控制问题,把PID部分代码拿出来分享一下。功能已经可以使用了,但还没有添加积分饱和处理,只在输出的时候做了范围限制。
Process_IPD.c 文件:
//==================================================================================================
//| 文件名称 | Mod_ProcessPID.c
//|--------- |--------------------------------------------------------------------------------------
//| 文件描述 | 过程PID 控制(增量式PID)
//|----------|--------------------------------------------------------------------------------------
//| 版本 | 时间 | 作者 | 描述
//|--------- |-------------|-----------|------------------------------------------------------------
//| V1.0 | 2011.11.15 | 侯功 | 规范化
//==================================================================================================
#include "..\TypeDefine.h"
#include "..\F28335\DSP2833x_Device.h"
#include "..\F28335\DSP2833x_Examples.h"
#include "..\Driver\Drv_GpioDef.h"
#include "..\Driver\Drv_LTC1867.h"
#include "..\Driver\Drv_Dac124s085.h"
#include "..\Driver\Drv_ADC_OnChip.h"
#include "..\ProAPI\ProAPI_ANALOG.h"
#include "Mod_ProcessPID.h"
//激光器电流控制默认参数
#define kDefaultCurrent 50//默认50毫安电流
#define kDefaultPID_K 5//默认的增益为5倍
#define kDefaultPID_T 5//默认控制周期为5秒
#define kDefaultPID_Ti 25//默认积分时间为5秒
#define kDefaultPID_Td 30//默认的微分时间为30秒
#define kDefaultSet 0.4//默认0.4毫安
//函数名:增量式PID参数初始化
//参数:PID_STRU 指针
//返回值:void
//作者:侯功 2011-11-15
void LD_Ctrl_PID_Init(PID_STRU * p_pid)
{
p_pid->set = kDefaultSet;//默认pd设置值0.2毫安 相当于激光器有50毫安驱动电流
p_pid->output = kDefaultCurrent;//默认激光器电流
p_pid->kp = kDefaultPID_K;//比例系数
p_pid->ti = kDefaultPID_Ti;//积分时间
p_pid->td = kDefaultPID_Td;//微分时间
p_pid->t = kDefaultPID_T;//控制周期
}
//函数名:增量式PId控制
//参数:PID_STRU 指针
//返回值:void
//作者:侯功 2011-11-15
void PID_GetValue(PID_STRU * p_pid)
{
INT16U i;
static INT8U counter = 0;
float err[3];
//
counter ++;
p_pid->input[2] = p_pid->input[1];
p_pid->input[1] = p_pid->input[0];
p_pid->input[0] = GetLaserIntensVol();
for(i=0;i<2;i++)
{
err = p_pid->set - p_pid->input;
}
//
if(counter > 2)
{
p_pid->output += p_pid->kp*(1+p_pid->ti/p_pid->t+p_pid->td/p_pid->t)*err[0];//比例项
p_pid->output += p_pid->kp*(1+2*p_pid->td/p_pid->t)*err[1];//积分项
//p_pid->output += p_pid->td*err[2]/p_pid->t;//微分项
}
}
Process_PID.h文件:
#ifndef MOD_PROCESSPID_H
#define MOD_PROCESSPID_H
typedef struct
{
float t;//采样周期
float kp;//比例系数
float ti;//积分时间
float td;//微分时间
float set;//设定值
float input[4];//输入缓存
float output;//输出
unsigned char flag;// 正/反 作用
}PID_STRU;
void LD_Ctrl_PID_Init(PID_STRU * p_pid);
void PID_GetValue(PID_STRU *);
#endif
使用步骤说明:
//step1 定义激光器控制参数
PID_STRU ld_current_ctrl;
//step2 初始化PID参数
LD_Ctrl_PID_Init(&ld_current_ctrl);
//step3 激光器电流PID控制主流程
void LD_CtrlProcess(void)
{
//电流PID控制
PID_GetValue(&ld_current_ctrl);
//范围保护
if(ld_current_ctrl.output < 5)
{
ld_current_ctrl.output = 0;
}
if(ld_current_ctrl.output > 100)
{
ld_current_ctrl.output = 100;
}
//设置激光器电流
SetLD_Current(ld_current_ctrl.output);
}
//step4 按照控制周期调用void LD_CtrlProcess(void) 函数