Hallo zusammen,
fuer mein Projekt - der Geschwindigkeitsregelung eines DC
Reihenschlussmotors bin ich gerade dabei eine gescheite regelung zu
entwerfen.
Geplant ist eine Kaskadenregelung mit Stromregler als Begrenzer im
inneren Regelkreis.
Dieser soll als PI Regler ausgelegt sein, mit der Stellgroesse des
Geschwindigkeitsreglers minus Strom als Regelgroesse und dem PWM
Verhaeltniss als Stellgroesse.
Die Pulsweite PW1 geht von 40000...0 (aus...ein).
Zunaechst moechte ich mal den P Anteil festlegen.
(Nach Ziegler/Nichols ist p = 0.45 * Pkrit, wo es grade zu schwingen
anfaengt)
Fuer den Fall das der Strom groesser wird als der Sollwert, wird der
Regelanteil (Abweichung = Soll - Ist) negativ. Da ich aber keine
negative Stellgroesse erzeugen kann, dachte ich mir ich begrenze diesen
auf 0, sprich PW1 = 40000.
Jedoch merke ich in der Praxis, dass bei solchen Stroemen der PW Wert
andauernd von aus auf x "springt" und nicht auf aus bleibt.
Koennte mir das nur dadurch erklaeren, dass die Stellgroesse immer nur
ganz kurz in die Begrenzung geht, der Strom sollte aber auf Grund der
Induktivitaet des Motors nicht so schnell folgen. Ich kappiers einfach
nicht.
Der Code des Reglers ist angehaengt, lauft auf nem C167.
Waere toll wenn, mir jemand helfen koennte.
1 | /* ----- A/D Conversion ready interrupt program ----------------------------- */
|
2 | void ad_int (void) interrupt 0x3F
|
3 | {
|
4 |
|
5 |
|
6 |
|
7 | ADST = 1; /* Conversion start */
|
8 |
|
9 | while(ADBSY) {}; /* wait of end of conversion */
|
10 |
|
11 | current = ADDAT & 0x03FF; /*read result of conversion */
|
12 |
|
13 |
|
14 |
|
15 | /* ----- PI current control ---------------------------------------- */
|
16 |
|
17 | current_error = (long) current_desired - (long) current;
|
18 |
|
19 | /*** set Deadband ***/
|
20 | current_error_temp = current_error;
|
21 | if (current_error_temp < 0)
|
22 | current_error_temp *= (-1);
|
23 | if (current_error_temp < 10) /* current error < 100mA */
|
24 | current_error = 0; /* set current error zero */
|
25 |
|
26 |
|
27 | /*** Calculate Proportional Term ***/
|
28 | current_proportional_term=(current_error*(long)current_proportional_gain);
|
29 |
|
30 |
|
31 | /*** Find Accumulated Error ***/
|
32 | if((current_controll_output>=0) && (current_controll_output<=40000))
|
33 | current_acc_error = ((long)current_acc_error) + (long)current_error;
|
34 |
|
35 |
|
36 | /*** Calculate Integral Term ***/
|
37 | current_integral_term = (current_acc_error*(long)current_integral_gain) ;
|
38 |
|
39 | /*** Check For Integral Term Out Of Range & Apply Saturation ***/
|
40 | current_integral_term_temp = ((long)current_acc_error * (long)current_integral_gain) ;
|
41 |
|
42 | if(current_integral_term_temp >= 40000) {
|
43 | current_integral_term = 40000 ;
|
44 | }
|
45 | else {
|
46 | if(current_integral_term_temp <= 0) {
|
47 | current_integral_term = 0 ;
|
48 | }
|
49 | }
|
50 |
|
51 |
|
52 |
|
53 |
|
54 | /*** Sum Up Control Terms ***/
|
55 | current_controll_output = (long) current_integral_term ;
|
56 | current_controll_output += current_proportional_term ;
|
57 |
|
58 |
|
59 | /*** Limit Value Of Control Term ***/
|
60 | if(current_controll_output >= 40000) {
|
61 | current_controll_output = 40000 ;
|
62 | }
|
63 | else {
|
64 | if(current_controll_output <= 0) {
|
65 | current_controll_output = 0 ;
|
66 | }
|
67 | }
|
68 |
|
69 | PW1 = 40000 - (short)current_controll_output;
|
70 |
|
71 | PWMIR = 0;
|
72 |
|
73 | }
|
so far...