|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
位置式 PID 控制算法
; ^ M6 H M1 y# K3 @0 t; w4 o ~. h
在使用单片机作为控制 cpu 时,请稍作简化,具体的 PID 参数必须由具体对象通过实验确定。由于单片机的处理速度和 ram 资源的限制,一般不采用浮点数运算,而将所有参数全部用整数,运算到最后再除以一个 2 的 N 次方数据(相当于移位) ,作类似定点数运算,可大大提高运算速度,根据控制精度的不同要求,当精度要求很高时,注意保留移位引起的 “余数 ”,做好余数补偿。这个程序只是一般常用 pid 算法的基本架构,没有包含输入输出处理部分。
0 f: i; l9 \! ?
V5 ~6 w* @6 d. E5 z( b#include <string.h>
- A2 N: C) I2 } j6 n#include <stdio.h>
6 F4 Z' s9 ^8 t9 b" u# ] L
1 h4 x. {3 m9 D6 MPID Function 1 g4 U& z. |2 }; }$ @3 _
The PID function is used in mainly
( P2 n1 g0 ?0 R& N9 _ q+ xcontrol applications. PID Calc peRForms one iteration of the PID 7 P2 H ?# Q' f0 m
algorithm. ' C# k( b5 l+ J: h( F
While the PID function works, main is just a dummy program showing
4 U+ T) t9 s* L3 p. wa typical usage. $ t8 b0 L1 A: P* [, ]" y
) J8 s9 l% c% H& ?5 _! ^6 HPID 功能* J/ m* c# K! x3 b! r0 _- L- s
在 PID 功能主要用于控制应用。 PID 计算器执行一个 PID 的迭代算法。虽然 PID 功能的工程,
# H, d5 x. @5 _5 B+ g主要只是一个虚拟程序显示一个典型的使用。
1 ~1 [1 r, \. h2 ctypedef struct PID {
8 C! C& O+ [0 ldouble SetPoint; // 设定目标 Desired Value
, i. u) |: D. F0 sdouble Proportion; // 比例常数 Proportional Const
6 J3 A2 S$ O* }6 X m5 n. ?3 [double Integral; // 积分常数 Integral Const
3 l* C. o+ d. ~- y3 mdouble Derivative; // 微分常数 Derivative Const 3 }$ @, m& K: s+ p
double LastError; // Error[-1]
: Q& C: @$ g; wdouble PrevError; // Error[-2]
0 L, a. O2 |6 L# \) p7 c3 Udouble SumError; // Sums of Errors
7 u p8 B7 e3 p$ G% A} PID;
+ M4 z+ P; k2 v' ]; R+ hdouble PIDCalc( PID *pp, double NextPoint )
* d1 k% Z. y6 j{ + m* t/ P% q6 u+ R$ ~
double dError, Error; * U1 J& g* w! \4 v7 v: O1 p
Error = pp->SetPoint - NextPoint; // 偏差
: i8 \) S* a4 R: L- i1 D+ K5 ^! E1 R/ c/ E
. t9 E' L- P3 L5 Y- c) a. m8 ^8 g
pp->SumError += Error; // 积分5 j3 D, E5 K: k, B
dError = pp->LastError - pp-> PrevError; // 当前微分
2 M) G2 Y( N/ t, H# [pp-> PrevError = pp->LastError;
; K$ l7 j! J) z' H$ A' Z3 @pp->LastError = Error; % r5 n0 D6 h, }. r4 a
return (pp-> Proportion * Error // 比例项6 u. N* S& O9 c ^3 ~! y
+ pp->Integral * pp->SumError // 积分项, @/ n* r: U) k b" z
+ pp->Derivative * dError // 微分项- G: L6 j/ \% ~! a8 D) V0 c! D8 X
);
& o2 d/ r) x M. I) T4 `. u8 R} " n; T' z% U, a$ I; S
/*======================= 初始化的 PID 结构 Initialize PID
2 R0 ^9 x; [$ E0 WStructure===========================*/
* ~$ _! }7 k5 h) @6 vvoid PIDInit (PID *pp)
3 ^8 m' ^" f" B0 A/ h' x" R+ B{
) M/ Z; m' _7 L6 ^. `% x& Pmemset ( pp,0,sizeof(PID)); 2 j2 o; C$ _4 @ B$ `" x& N* u
} 3 ~9 {- \' v+ n& \! `
/*======================= 主程序 Main ( D; W, u: D% `8 u' c
Program=======================================*/
8 f# a$ X! {* ]' ?# c+ \9 } ]double sensor (void) // 虚拟传感器功能 Dummy Sensor Function{ return 100.0;}
' g6 T0 `8 E" a" c3 Ivoid actuator(double rDelta) // 虚拟驱动器功能 Dummy Actuator Function{}
8 a3 \3 b F& V& e2 {" G* qvoid main(void)
5 N' d* Q% b8 e9 x/ [7 K{ ) j1 R) _2 ~' h" B5 u1 C
PID sPID; // PID 控制结构 PID Control Structure ! s0 G9 d c: |; Z* h: K' `* S
double rOut; // PID 响应(输出) PID Response (Output) # l. d/ M. }) g( d" X- q! M6 D' L- W
double rIn; // PID 反馈(输入) PID Feedback (Input)
% V# P& @" ^' I( l% h( qPIDInit ( &sPID ); // 初始化结构 Initialize Structure % e% E% T: @% z2 C) d4 S
sPID.Proportion = 0.5; // 设置 PID 系数 Set PID Coefficients ( g" |$ y% Q2 N$ V( h. O
sPID.Integral = 0.5;
& J8 [; w% r: V3 z zsPID.Derivative = 0.0;
+ q+ {0 ?- b; esPID.SetPoint = 100.0; // 设置 PID 设定 Set PID Setpoint
7 G8 h3 r2 C" |- Bfor (;;) - r; v0 s0 `& y) g5 y* q z
{ // 模拟最多的 PID 处理 Mock Up of PID Processing
- V5 w! [4 d+ [; P7 crIn = sensor (); // 读取输入 Read Input3 R; s8 n4 |4 x1 z, o
; V. x# K' @+ B" s' z. X0 g& o1 a) E! k' |& _
rOut = PIDCalc ( &sPID,rIn ); // 执行的 PID 迭代 Perform PID Interation ; j" p i- J0 J1 k
actuator ( rOut ); // 所需的更改的影响 Effect Needed Changes% K0 T; N+ p% ~; v
$ {: z. F% }- y' }
: M! s- a; Y& F
; c/ B0 p/ A; r& J7 u8 I0 |+ V- Q1 n3 c
) @% j8 L/ g( Q& @6 z: f& Z$ P4 Y
|
|