|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
位置式 PID 控制算法
' I' D% q' \( X& a+ t' s u: m$ P; s7 o+ {- A. K
在使用单片机作为控制 cpu 时,请稍作简化,具体的 PID 参数必须由具体对象通过实验确定。由于单片机的处理速度和 ram 资源的限制,一般不采用浮点数运算,而将所有参数全部用整数,运算到最后再除以一个 2 的 N 次方数据(相当于移位) ,作类似定点数运算,可大大提高运算速度,根据控制精度的不同要求,当精度要求很高时,注意保留移位引起的 “余数 ”,做好余数补偿。这个程序只是一般常用 pid 算法的基本架构,没有包含输入输出处理部分。# P- F! {, M1 T# d: {4 }: U2 L
! j B% B; C' G7 P/ \$ l#include <string.h> ' O+ h$ q8 v4 I( V: r1 K$ }$ m
#include <stdio.h>
( \; L9 _" j8 K4 v6 V7 N7 ]) Z- T" ^' W1 ^% M% v3 j
PID Function
# v' q% \3 }1 l" a6 H9 mThe PID function is used in mainly
! P' f& j8 k1 [. b4 Econtrol applications. PID Calc peRForms one iteration of the PID
0 m n6 d# k9 K ~+ ualgorithm. 1 W1 P. A2 t5 n' [) \
While the PID function works, main is just a dummy program showing
9 |) ?4 L0 w1 i; w+ Ia typical usage. - U9 N9 {) ], G4 v! m& a' [. d
3 I$ }! n7 A2 e% w ]/ x- C9 u, e
PID 功能, q; l% C" _( }" ]
在 PID 功能主要用于控制应用。 PID 计算器执行一个 PID 的迭代算法。虽然 PID 功能的工程,4 T# _) L J8 J. {7 U3 B% l& j
主要只是一个虚拟程序显示一个典型的使用。% F& V+ Y8 V8 M9 W3 H/ t% Z1 A
typedef struct PID { & p4 c& x8 k' @% U8 F. P0 n
double SetPoint; // 设定目标 Desired Value ) p7 o' G0 j8 f: y
double Proportion; // 比例常数 Proportional Const ! P* n2 g. x% T ^, x
double Integral; // 积分常数 Integral Const
4 G3 x; U- A5 C) I0 y7 T4 }double Derivative; // 微分常数 Derivative Const
$ d2 l: ~2 S4 x$ b) ~6 f# o, Pdouble LastError; // Error[-1]
# h! K0 `# N0 K* {double PrevError; // Error[-2] - M5 |/ N$ L3 {' T$ j* R
double SumError; // Sums of Errors
( u* s/ n0 }. E# ^- ^, b8 P% o} PID;
# G3 i! I3 s) T- l( jdouble PIDCalc( PID *pp, double NextPoint ) ' D: ]8 Q3 }9 s s
{
q' [- Q5 D! ~ V. \7 [0 @$ ~5 rdouble dError, Error;
& [: \1 M5 B3 I0 R' d2 i( W: dError = pp->SetPoint - NextPoint; // 偏差7 v- w4 d/ V- d1 a1 W8 S( W; [
& A6 f ]$ p& H1 f( }- h
$ p5 ?; j& R( w( `' ^pp->SumError += Error; // 积分
; ]& T/ D4 l- U* h& hdError = pp->LastError - pp-> PrevError; // 当前微分% z/ j' C+ r! }7 |# z
pp-> PrevError = pp->LastError;
' H* Y7 j e9 Y1 Q F$ d# u c/ ypp->LastError = Error; % s8 s1 Q: m+ }7 b! K* A: }
return (pp-> Proportion * Error // 比例项
" _5 C6 |, ~7 f8 O+ pp->Integral * pp->SumError // 积分项" H: y1 x& Y0 m1 \ R
+ pp->Derivative * dError // 微分项) a8 \3 B3 N' u/ g7 ^
); 9 f: u% P6 ^- w( O) |% `* p8 Q
}
( O" F: a( {" U ?/*======================= 初始化的 PID 结构 Initialize PID + g' x1 i' \" V3 [3 w# ^ G7 W0 c
Structure===========================*/ 9 K5 n: K* c. k7 M
void PIDInit (PID *pp) 2 S1 z( ^9 {* d" J/ z
{
& U; q3 P+ B- ]4 umemset ( pp,0,sizeof(PID));
0 p$ S S$ U# j} # s; e" N% w+ @+ o) }4 A6 `
/*======================= 主程序 Main
- b! ~ Q9 V' aProgram=======================================*/
# ]5 I1 ?7 m( z" u6 U- c9 {0 R. ]( sdouble sensor (void) // 虚拟传感器功能 Dummy Sensor Function{ return 100.0;} ]7 A7 h; e; Z8 `
void actuator(double rDelta) // 虚拟驱动器功能 Dummy Actuator Function{} 7 Y5 ~9 F) }+ l8 D
void main(void) / G' e: J T. T8 ?4 F1 C
{
9 X3 A6 [! k' F/ d4 oPID sPID; // PID 控制结构 PID Control Structure : D0 }7 \( V/ a7 o3 ?
double rOut; // PID 响应(输出) PID Response (Output)
. { u# o) Y# o3 j6 w6 {9 Cdouble rIn; // PID 反馈(输入) PID Feedback (Input)
% v. _/ I/ A- P) VPIDInit ( &sPID ); // 初始化结构 Initialize Structure 2 S. `( A& l, d5 U+ Z4 x0 n" f
sPID.Proportion = 0.5; // 设置 PID 系数 Set PID Coefficients ! V7 L# i% H' m/ h; W9 w# [
sPID.Integral = 0.5;
6 Y& b% y" O7 k! J$ @sPID.Derivative = 0.0;
. L7 n) E+ a8 f) usPID.SetPoint = 100.0; // 设置 PID 设定 Set PID Setpoint
$ b6 R, G4 b- mfor (;;)
+ M, \; k3 l: P+ F% R. N3 P( H5 P{ // 模拟最多的 PID 处理 Mock Up of PID Processing 8 r6 w6 X- O/ Z) ^, A
rIn = sensor (); // 读取输入 Read Input
5 d) x( Q2 T0 `: w3 T! L) b1 I$ q0 K3 O: e$ ~
1 z+ P0 K% ]- y2 `% ]rOut = PIDCalc ( &sPID,rIn ); // 执行的 PID 迭代 Perform PID Interation
0 h: S6 N" M; X& Uactuator ( rOut ); // 所需的更改的影响 Effect Needed Changes& D# V% E( A5 X4 S5 D4 Z
. M4 H8 G' P* f" o
9 p+ E! a$ O# V3 i+ ^
4 w4 i. u! |' j. v) f2 Q. ]
2 r+ i g% k. `* v# M
! G1 d+ j [2 u
' @0 N* l0 Q9 I5 |6 G) \ |
|