Hallo Leute, ich habe eine kleine Frage: Ich bin dabei eine Zustandsregelung auf einem ATMega32 zu realisieren und brauche dazu eine konstante Abtastzeit bzw. eine Zykluszeit des Programmes die ich genau kenne, denn danach richtet sich die Berechnung der Stellgröße. Mir fallen hierzu mal grob 2 Möglichkeiten ein: 1. In der Simulation die Clocks zählen und dadurch die Zykluszeit ermitteln -> aufwendig und muss bei jeder Programmänderung wieder neu durchgeführt werden 2. Mittels einem Timer Interrupt eine definierte Aufrufezeit meines Programmes zu definieren. Ich habe aber gehört, dass die Interruptroutinen so kurz wie möglich gehalten werden sollen - und mit dieser Variante würde mein gesamtes Programm in einer einzigen ISR stehen, kann mir das Probleme bereiten? Wie sieht es da dann mit der Variablendeklararion aus, Stichwort volatile? Die Zykluszeit wird so gewählt, dass sichergestellt ist, dass der Regelalgorythmus zu 100% ganz bis zum Ende duchlaufen ist. Lieber wäre mir Variante 2, aber funktioniert es, wenn ich das so mache? fg
Franz Spanlang schrieb: > 2. Mittels einem Timer Interrupt eine definierte Aufrufezeit meines > Programmes zu definieren. Ich habe aber gehört, dass die > Interruptroutinen so kurz wie möglich gehalten werden sollen in der ISR nur ein flag setzen und das in der main auswerten...
Variante 3: in der ISR nur ein Flag setzen In der Main auf dieses Flag warten, es zurücksetzen, und die nächste Rechenrunde starten.
Nebenbei, ich habe Variante 2 auch schon erfolgreich praktiziert mit einer Beobachterbasierenden Kaskadenregelung für einen DC-Motor. Da der Regler nur 30µs Rechenzeit gebraucht hat, war das kein Problem. (auf einem AT90CAN128) -> Lass deinen Regler erstmal im Simulator laufen und sieh dir an wie lange die Berechungen brauchen. Dann siehst du schon obs kritisch ist.
@ Franz Spanlang (spanti) >1. In der Simulation die Clocks zählen und dadurch die Zykluszeit >ermitteln -> aufwendig und muss bei jeder Programmänderung wieder neu >durchgeführt werden Macht man nur bei sehr einfachen Sachen in Assembler. In C ziemlich sinnlos. >2. Mittels einem Timer Interrupt eine definierte Aufrufezeit meines >Programmes zu definieren. Genau so. > Ich habe aber gehört, dass die >Interruptroutinen so kurz wie möglich gehalten werden sollen Das ist alles relativ. Ein Timerinterrupt alle 1ms darf auch mal 9ms dauern, siehe Artikel Interrupt. >stehen, kann mir das Probleme bereiten? Ja, wenn deine ISR zu lange braucht. > Wie sieht es da dann mit der >Variablendeklararion aus, Stichwort volatile? Siehe Interrupt. > Die Zykluszeit wird so >gewählt, dass sichergestellt ist, dass der Regelalgorythmus zu 100% ganz >bis zum Ende duchlaufen ist. Na dann ist ja alles paletti. >Lieber wäre mir Variante 2, aber funktioniert es, wenn ich das so mache? Ja. MfG Falk
Hallo Leute, Danke für die schnellen Antworten! Also das mit dem Flag setzen ist echt eine hervorragende Lösung! Das heißt die Flagvariable muss dann logischerweise global und volatile sein, oder? Und das ganze Programm ist dann eine einzige if-Abfrage der Flag variable in der main Methode, wo dann der gesamte Code für die Regelung enthalten ist. Nochmals vielen Dank, ich glaube so müsste es funktionieren!
Um Strom zu sparen, kannst Du nach jedem Zyklusdurchlauf den MC in den Sleepmodus schicken, durch den Timer Interrupt wird er wieder aufgeweckt und der nächste Zyklus läuft pünktlich wieder durch.
Also ich habe ein Computernetzteil mit -zig Ampere zur Verfügung, der Stromverbrauch stellt demzufolge kein Problem dar. Aber wenn ich den µC in den Sleepmodus versetze, braucht er da nicht jedes mal wieder eine bestimmte Zeit um den ADC zu initialisieren? Weil ich lese in jedem Zyklus Werte vom ADC ein.
@ Franz Spanlang (spanti) >in den Sleepmodus versetze, braucht er da nicht jedes mal wieder eine >bestimmte Zeit um den ADC zu initialisieren? Nein, siehe Sleep Mode. Man musse es aber mit dem Stromsparen nicht übertreiben. MFG Falk
Andreas R. schrieb > Nebenbei, ich habe Variante 2 auch schon erfolgreich praktiziert mit > > einer Beobachterbasierenden Kaskadenregelung für einen DC-Motor. Da der > > Regler nur 30µs Rechenzeit gebraucht hat, war das kein Problem. (auf > > einem AT90CAN128) > @ Andreas ich bin auch dabei eine kasladeregelung im µC zu implementieren.mit Interrup habe ich schon den Stromregler programmiert und es funktionier. jetzt will ich erweiter, damit die Spannung auch geregelt wird aber weiß nicht on ich ein weites Interrupt brauche oder nicht und wenn ja wie soll ich die beide im programm ordnen.
Franz Spanlang schrieb: > Danke für die schnellen Antworten! Also das mit dem Flag setzen ist echt > eine hervorragende Lösung! Das heißt die Flagvariable muss dann > logischerweise global und volatile sein, oder? ... Klar. Ich nehme auch gerne mal die GPIO-Register dafür!
Falk Brunner schrieb: > Das ist alles relativ. Ein Timerinterrupt alle 1ms darf auch mal 9ms > dauern, siehe Artikel Interrupt. Wenn alle 1ms ein Interupt auftritt der 9ms dauert ob das gut geht ;) Sicherlich meinst du 1s Franz Spanlang schrieb: > und mit dieser Variante würde mein gesamtes Programm > in einer einzigen ISR stehen Ist an sich kein Problem solange die Ausführungszeit kleiner der Aufrufzeit ist. Volatile muß dann auch nix sein. Das brauchst du nur wenn du dem Compiler mitteilen willst, das sich außerhalb seines Sichtbarkeitbereiches der Inhalt einer Variablen ändern kann oder der Zugriff darauf Seiteneffekte hat. In der "main" kannst du deinen prozessor dann einfach in den sleep mode versetzen und dann sparst du sogar noch strom damit.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.