regelung5a.c


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
   }