PID控制C源程序
2013-04-03
标签: PID

PID控制C源程序,可以参考一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
struct _pid {
    int pv; /*integer that contains the process value*/
    int sp; /*integer that contains the set point*/
    float integral;
    float pgain;
    float igain;
    float dgain;
    int deadband;
    int last_error;
};
struct _pid warm, *pid;
int process_point, set_point, dead_band;
float p_gain, i_gain, d_gain, integral_val, new_integ;;
/*------------------------------------------------------------------------
pid_init
DESCRIPTION This function initializes the pointers in the _pid structure
to the process variable and the setpoint. *pv and *sp are
integer pointers.
------------------------------------------------------------------------*/
void pid_init(struct _pid *warm, int process_point, int set_point)
{
    struct _pid *pid;
    pid = warm;
    pid->pv = process_point;
    pid->sp = set_point;
}
/*------------------------------------------------------------------------
pid_tune
DESCRIPTION Sets the proportional gain (p_gain), integral gain (i_gain),
derivitive gain (d_gain), and the dead band (dead_band) of
a pid control structure _pid.
------------------------------------------------------------------------*/
void pid_tune(struct _pid *pid, float p_gain, float i_gain, float d_gain, int dead_band)
{
    pid->pgain = p_gain;
    pid->igain = i_gain;
    pid->dgain = d_gain;
    pid->deadband = dead_band;
    pid->integral = integral_val;
    pid->last_error = 0;
}
/*------------------------------------------------------------------------
pid_setinteg
DESCRIPTION Set a new value for the integral term of the pid equation.
This is useful for setting the initial output of the
pid controller at start up.
------------------------------------------------------------------------*/
void pid_setinteg(struct _pid *pid, float new_integ)
{
    pid->integral = new_integ;
    pid->last_error = 0;
}
/*------------------------------------------------------------------------
pid_bumpless
DESCRIPTION Bumpless transfer algorithim. When suddenly changing
setpoints, or when restarting the PID equation after an
extended pause, the derivative of the equation can cause
a bump in the controller output. This function will help
smooth out that bump. The process value in *pv should
be the updated just before this function is used.
------------------------------------------------------------------------*/
void pid_bumpless(struct _pid *pid)
{
    pid->last_error = (pid->sp) - (pid->pv);
}
/*------------------------------------------------------------------------
pid_calc
DESCRIPTION Performs PID calculations for the _pid structure *a.
This function uses the positional form of the pid equation,
and incorporates an integral windup prevention algorithim. Rectangular integration is used,
so this function must be repeated on a consistent time basis for accurate control.
RETURN VALUE The new output value for the pid loop.
USAGE #include "control.h"*/
float pid_calc(struct _pid *pid)
{
    int err;
    float pterm, dterm, result, ferror;
    err = (pid->sp) - (pid->pv);
    if (abs(err) > pid->deadband) {
        ferror = (float) err; /*do integer to float conversion only once*/
        pterm = pid->pgain * ferror;
        if (pterm > 100 || pterm < -100) {
            pid->integral = 0.0;
        }
        else {
            pid->integral += pid->igain * ferror;
            if (pid->integral > 100.0) {
                pid->integral = 100.0;
            }
            else if (pid->integral < 0.0) {
                pid->integral = 0.0;
            }
        }
        dterm = ((float)(err - pid->last_error)) * pid->dgain;
        result = pterm + pid->integral + dterm;
    }
    else {
        result = pid->integral;
    }
    pid->last_error = err;
    return (result);
}
void main(void)
{
    float display_value;
    int count = 0;
    pid = &warm;
// printf("Enter the values of Process point, Set point, P gain, I gain, D gain \n");
// scanf("%d%d%f%f%f", &process_point, &set_point, &p_gain, &i_gain, &d_gain);
    process_point = 30;
    set_point = 40;
    p_gain = (float)(5.2);
    i_gain = (float)(0.77);
    d_gain = (float)(0.18);
    dead_band = 2;
    integral_val = (float)(0.01);
    printf("The values of Process point, Set point, P gain, I gain, D gain \n");
    printf(" %6d %6d %4f %4f %4f\n", process_point, set_point, p_gain, i_gain, d_gain);
    printf("Enter the values of Process point\n");
    while (count <= 20) {
        scanf("%d", &process_point);
        pid_init(&warm, process_point, set_point);
        pid_tune(&warm, p_gain, i_gain, d_gain, dead_band);
        pid_setinteg(&warm, 0.0); //pid_setinteg(&warm,30.0);
//Get input value for process point
        pid_bumpless(&warm);
// how to display output
        display_value = pid_calc(&warm);
        printf("%f\n", display_value);
//printf("\n%f%f%f%f",warm.pv,warm.sp,warm.igain,warm.dgain);
        count++;
    }
}


可能会用到的工具/仪表
本站简介 | 意见建议 | 免责声明 | 版权声明 | 联系我们
CopyRight@2024-2039 嵌入式资源网
蜀ICP备2021025729号