Forum: Mikrocontroller und Digitale Elektronik i & u_regler ist alles richtig


von Anfänger (Gast)


Lesenswert?

Hallo Zusammen,

ich komme wieder nach ein paar Tage, ich habe mein Program noch mal 
bearbeiten und kann separat ein spannungsregler laufen lassen, nur dass 
die Optimierung fehlt. jetzt wollte ich weiter mit der kaskadierung 
anfangen und wie folg


__irq void IRQ_Handler(void)     // Interrupt alle 100µs

{
if((IRQSTA & RTOS_TIMER_BIT) !=0)   // Frage nach der Quelle des 
Interrupts
  {

ADCCON = 0x6A0;   // single-ended Mode, start konv.
ADCCP=0;         // Auswahl kanal 0 für ist-strom
ADCCON = 0x6A3;
while (!ADCSTA){};            // warten bie Ende der Wandlung
x1_value = (ADCDAT >> 16);      // Ergebnis der Wandlung in Variable

ADCCON = 0x6A0;
ADCCP=1;             soll_strom
ADCCON = 0x6A3;
while (!ADCSTA){};
w1_value = (ADCDAT >> 16);

--- kanal2  ist_spannung

---- kanal3 soll_spannung

if(x1_value >= w1_value){
stellglied=PI_Berechnung(x1_value, w1_value);           // Aufrufe PI 
routine für strom regler
DAC1DAT=(stellglied << 16 ) ;           // Ausgabe
}
flag++;    // curent Tick value Timer0
IRQEN = RTOS_TIMER_BIT;    // Timer0-Interrupt  Aktivieren

}
Return

}
************************************************************************

Main()
{
init uart
init ADC
init timet
enable timer-interrupt

while(1)
{
  while(!(flag++==10));
  flag++=0;

  PID_Sapnnung(x_u, w_u)

  sprintf(array,"x=%d ",x1_value);
  write(0,array);
   ----
   ----
  sprintf(array,"w=%d ",w1_value);
  write(0,array);

}

********************************************************************+

int PI_strom( int x_i, int w_i)
{



  x_i_normiert= (x_i1 << 3);    // Normierter Istwert  w_i_normiert= 
(w_i1 << 3);    // Normierter sollwert 
e_i_normiert=x_i_normiert-w_i_normiert;//   Regelabweichung
  e_i= e_i_normiert/8; 
esum_i_normiert=esum_i_normiert +  e_i_normiert;    // normierte Summe 
der Regelabweichung

         // Begrenzung Anti windup  ??

  temp1=(kp << 3) * e_i_normiert;  // fixed point mit 3 Nachkoma
  temp1=temp1+(1<<(n-1));
  temp1=temp1/8;
  if (temp1 > Max){
    yp_i_normiert=Max;}
  else if(temp1 < Min){
    yp_i_normiert=Min;}
  else
    yp_i_normiert=temp1/8;

  temp2=( (303 << 3) *(esum_i_normiert)); // ki*ta*10000=303
  temp2=temp2 + (1<<(n-1));
  temp2=temp2/8;
  if (temp2 > Max){
    yi_i_normiert=Max;}
  else if(temp2 < Min){
    yi_i_normiert=Min;}
  else
    yi_i_normiert=temp2/8;

  y_i_normiert= (yp_i_normiert/1000 + yi_i_normiert/10000);
          y_i=y_i_normiert/8  ;    Stellglied der Regler
                 if(y_i<2978){
    y_i=2978;
  }
  else
    if(y_i>3276){
         y_i=3276;
    }

  return y_i;                              }

die routine für Spannung allein funktioniert und jetzt will ich die 
beide kaskadieren wie die analoge schaltung funktioniert.
die stromregler  ist schneller ist im prinzip ein strombrgrenzung und 
die PI_strom start nur wenn die x_i den  w_i erreicht oder über  ist. 
und wenn der Fall kommt dann schaltet die PID_spannung ab. und pi_strom 
ist aktiv.
deswegen denke ich an einem Timer-interrupt, das alle 100µ kommt.  die 
werte werden dann gelesen und einem Vergleich zwischen x_i und w_i wird 
gemacht. wenn x_i >>= w_i ist , dann aufrufe von PI_strom und stellglied 
im DAC zuweisen und der flag inkrementieren.  im main flag wird gefrag. 
wenn flag 10 erreicht hat, sind jetzt 10* 100µs d.h 1ms gelaufen ,dann 
rufe von PID_spannung.
das konzept ist schon ok?
wenn ja, wie und wo genau soll ich das Interrupt sperren und freigeben.

ich will auch werte ausgeben, vor allem wo,dies möglich ist.  beim test 
von PI_routine habe einige werte mit der Funktion unten am Hyper 
Terminal geschickt. Aber dies kostet viel Zeit.
kann man anders und einfacher mit weniger zeitkosten werten am HP 
schicken? und wie? ich will  zb  solche anzeige   yp=222
                yi=xxxx,yyy ich arbeite mit fixed point number





int putchar(int ch)  {                   /* Write character to Serial 
Port  */

  if (ch == '\n')  {
      while(!(0x020==(COMSTA0 & 0x020)))
      {}
    COMTX = CR;              /* output CR */
    }
    while(!(0x020==(COMSTA0 & 0x020)))
    {}

   return (COMTX = ch);
}

void write (int file, char * ptr ) {
  //int i;
 // for (i = 0; i < len; i++)
 while(!(*ptr == 0))
 putchar (*ptr++);
  //return len;

}

bitte alle zu gucken und idee geben.
Grüß

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.