www.mikrocontroller.net

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


Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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üß

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.