1 | /*===========================================================================*/
|
2 | /* Filename: regelung4a.c Name: XXXXXXXXX */
|
3 | /* Project: Motoransteuerung/regelung Date: 25.01.03 */
|
4 | /*===========================================================================*/
|
5 |
|
6 | #include <90s8535.h>
|
7 | #define uchar unsigned char
|
8 | #define uint unsigned int
|
9 |
|
10 | #define LEDS 0x04
|
11 | #define AMPEL 0x05
|
12 |
|
13 | #define SEG7Z 0x06
|
14 | #define SEG7E 0x07
|
15 |
|
16 | void init (void);
|
17 | void wait_us (uint tus);
|
18 | void wait_ms (uint tms);
|
19 | void set_mux (uchar mux);
|
20 | void wr_data (uchar data);
|
21 | void wr_seg7 (uchar data);
|
22 | int read_adc (uchar ch);
|
23 |
|
24 | float Ta,Tn,kr,x,w,en,en_1,yn,yn_1,kphi,ua,ia,n,Ra,nmax; // Variablendeklaration
|
25 | float adcu,adci,adcw; // Variablendeklaration
|
26 | uchar i,k,kproz,e,z;
|
27 | void main (void)
|
28 | {
|
29 | init(); // Initialisierung der PORT's und der T/C'er für PWM
|
30 | for (;;) // andere Form der Endlosschleife
|
31 | {
|
32 | /* Variablendefinition */
|
33 | uchar tmp1;
|
34 | Ta = 0.0005; // 0,5 ms Abtastzeit
|
35 | Tn = 0.02; // Tn = T1 = 20 ms geschätzt
|
36 | kr = 2.0; // erster Versuchswert war 5, durch probieren 2 ermittelt!
|
37 | yn = 0.0; // Stellgrösse
|
38 | yn_1 = 0.0; // Vorgeschichte der Stellgrösse
|
39 | en = 0; // Regelabweichung
|
40 | en_1 = 0; // Vorgeschichte der Regelabweichung
|
41 | Ra = 7.0; // Ankerkreiswiderstand gemessen in Ohm
|
42 | kphi = 0.04; // k * phi aus Leerlaufdaten ermittelt
|
43 | nmax = 333.0; // max. Drehzahl = Bezugswert für Normierung in 1/sec ;
|
44 |
|
45 | /* - Sollwert ermitteln - */
|
46 | adcw = read_adc (7); // einlesen des analogen Sollwertes 0 bis 5V und wandeln auf Zahlen 0 bis 1023
|
47 | w = adcw / 1024; // Normierung des Sollwertes w auf 0 bis 1;
|
48 |
|
49 | /* - Istwert ermitteln - */
|
50 | adcu = read_adc (6); // einlesen des analogen Istwertes der Ua: 0 bis 15V/10 = 1,5V
|
51 | // und wandeln auf Zahlen 0 bis 1023 * 1,5/5 = 0 .. 307
|
52 | adci = read_adc (5); // einlesen des analogen Istwert1,5/5 = 0 .. 307
|
53 | ua = (adcu / 1024) * 5.0 * 10.0; // Normierung und Umrechnung: Max. 8-bit-Wert = 5 V; Spgsteiler 1:10;
|
54 | ia = (adci / 1024) * 5.0; // Normierung und Umrechnung: Sps.abfall an 1 Ohmes des Ia: 0 bis 1,5A * 1Ohm = 1,5V
|
55 | // und wandeln auf Zahlen 0 bis 1023 * Meßwiderstand;
|
56 | n = (ua - (ia * Ra)) / kphi; // Drehzahlgleichung der GM; (15V -(0,3A * 7R)/0,04) = 321 /sec
|
57 | x = n / nmax; // Normierung auf Maximaldrehzahl (Leerlauf); ca. 0 .. 0.96 (<=1)
|
58 |
|
59 | /* - Istwert begrenzen - */
|
60 | if (x < 0.01) x = 0.01;
|
61 | if (x > 0.99) x = 0.99;
|
62 |
|
63 | /* - Ausgabe auf LED's- */
|
64 | k = (uchar)(x * 256);
|
65 | (uchar)kproz = 0;
|
66 | kproz = x*100;
|
67 |
|
68 | for (i=0; i<5; i++)
|
69 | {
|
70 | set_mux(LEDS);
|
71 | wait_ms (2);
|
72 | wr_data(k); // 0.01*225 .. 0.99*256 = 2 .. 253
|
73 |
|
74 | set_mux (SEG7Z);
|
75 | z = kproz/10;
|
76 | wr_seg7 (z);
|
77 | wait_ms (2);
|
78 |
|
79 | set_mux (SEG7E);
|
80 | e = kproz -(z*10);
|
81 | wr_seg7 (e);
|
82 | wait_ms (2);
|
83 | }
|
84 |
|
85 |
|
86 | /* Regeldifferenz e berechnen und Vorgeschichte speichern */
|
87 | en_1 = en;
|
88 | en = w - x;
|
89 | yn_1 = yn;
|
90 |
|
91 | /* Stellgröße y berechnen und begrenzen */
|
92 | yn = yn_1 + kr * (en - en_1 + Ta/Tn * en); // PI - Regleralgorithmus - Stellgrösse y ermitteln;
|
93 | if (yn < 0.01) yn = 0.01; // Begrenzung auf 0.01 .. 0.99
|
94 | if (yn > 0.99) yn = 0.99;
|
95 |
|
96 | /* Stellgröße y ausgeben = PWM-Schwelle setzen */
|
97 | tmp1 = (uchar)(yn * 256); // Vergleichswert für 8bit PWM
|
98 | OCR1A = tmp1; // für PWM-Ausgabe auf CIF 1.3 auf Oszi;
|
99 | OCR1B = tmp1; // Motoransteuerung über Schalteinheit
|
100 |
|
101 | wait_us(100); // Abtastzeit von ca. 0.5 ms abwarten; Schätzung: 0,4 ms Schleifenlaufzeit
|
102 | }
|
103 | }
|
104 |
|
105 | void init (void)
|
106 | {
|
107 | /*--- Input/Output Ports initialization */
|
108 | DDRA = 0x00; /* alles Eingaenge, z.B. für ADC */
|
109 | DDRB = 0xFC; /* 0,1 Eingaenge für T0,T1; 2-7 Ausgaenge für MUX u. LCD*/
|
110 | PORTB = 0; /* hochohmiger Zustand*/
|
111 | DDRC = 0xFF; /* alles Ausgaenge (Datenbus) */
|
112 | PORTC = 0; /* hochohmiger Zustand*/
|
113 | DDRD = 0xB0; /* 10110000b, 4,5,7 PWM Ausgaenge */
|
114 | PORTD = 0; /* hochohmiger Zustand*/
|
115 |
|
116 | /*--- PWM initialisieren mit TimerCounter 1 ---*/
|
117 | TCCR1A = 0xA1; /* 1010 0001 COMPA + COMPB, Non Invert. PWM, 8bit */
|
118 | TCCR1B = 0x02; /* CLK=8MHz/64 = 125kHz; 1 cnt = 8us für Oszi ! */
|
119 | }
|
120 |
|
121 | int read_adc (uchar ch)
|
122 | {
|
123 | uchar vadch, vadcl;
|
124 | int vadc;
|
125 | DDRA=0x00; // Port A is Input
|
126 | ADMUX=ch;
|
127 | ADCSR=0xC6; // 1100 0110 enable, start conv., one conv., /64 = 125 kHz
|
128 | wait_us (120); // 120us conversion Time, 1/125 kHz * 13 Zyklen = 104 us
|
129 | vadcl=ADCL;
|
130 | vadch=ADCH;
|
131 | vadc=0x100 * vadch + vadcl;
|
132 | return (vadc);
|
133 | }
|
134 |
|
135 |
|
136 | void wait_ms (uint tms)
|
137 | {
|
138 | uint ms;
|
139 | for (ms=1; ms<=tms; ms++)
|
140 | {
|
141 | wait_us (1000);
|
142 | };
|
143 | }
|
144 |
|
145 | void set_mux (uchar mux)
|
146 | {
|
147 | PORTB=mux<<5;
|
148 | }
|
149 |
|
150 | void wr_data (uchar data)
|
151 | {
|
152 | PORTC=data;
|
153 | }
|
154 |
|
155 | void wr_seg7 (uchar data)
|
156 | {
|
157 | uchar seg7;
|
158 | data &= 0x0F;
|
159 | switch (data)
|
160 | {
|
161 | case 0x00: seg7 = 0xFC; break; // 1111 1100b
|
162 | case 0x01: seg7 = 0x60; break; // 0110 0000b
|
163 | case 0x02: seg7 = 0xDA; break; // 1101 1010b
|
164 | case 0x03: seg7 = 0xF2; break; // 1111 0010b
|
165 | case 0x04: seg7 = 0x66; break; // 0110 0110b
|
166 | case 0x05: seg7 = 0xB6; break; // 1011 0110b
|
167 | case 0x06: seg7 = 0xBE; break; // 1011 1110b
|
168 | case 0x07: seg7 = 0xE0; break; // 1110 0000b
|
169 | case 0x08: seg7 = 0xFE; break; // 1111 1110b
|
170 | case 0x09: seg7 = 0xF6; break; // 1111 0110b
|
171 | case 0x0A: seg7 = 0xEE; break; // 1110 1110b
|
172 | case 0x0B: seg7 = 0x3E; break; // 0011 1110b
|
173 | case 0x0C: seg7 = 0x9C; break; // 1001 1100b
|
174 | case 0x0D: seg7 = 0x7A; break; // 0111 1010b
|
175 | case 0x0E: seg7 = 0x9E; break; // 1001 1110b
|
176 | case 0x0F: seg7 = 0x8E; break; // 1000 1110b
|
177 | }
|
178 | wr_data (seg7);
|
179 | }
|
180 |
|
181 | void wait_us (uint tus)
|
182 | {
|
183 | uchar cnt;
|
184 | TCCR0=0x03; // CLK/64: 8MHz/64 = 125kHz, 1 cnt = 8us
|
185 | TCNT0=0x00; // clear CTR0
|
186 | cnt = (uchar) (tus/8);
|
187 | while (TCNT0 < cnt)
|
188 | { /* warten */ }
|
189 | }
|