Hallo, sollte man bei PID-Regler die Zwischenergebnisse auf Overflow prüfen? z.B. ist der I-Anteil: i = iAlt + Regelabweichung; iAlt = i; Und da kann die i Variable schnell in Überlauf bzw. Unterlauf kommen. Wie managet ihr das? Vielleich hat jemand ein PID-Regler-Code in C zeigen? Wäre echt lieb.. Danke!
if (sixi > 255) // Begrenzung I-Anteil sixi = 255; if (sixi < -255) sixi = -255; sixi --> signed integer 16Bit
Hallo, wenn die Varieble bei einer Addition überläuft, wird sie nicht mehr größer sein als ein Grenzwert, sondern eventuell sogar negativ. Man sollte besser das Overflowflag der ALU der CPU abfragen. Dort wird ein Overflow festgehalten. Wenn das passiert ist, kann man den Maximalwert der Variable setzen. Grüße, Peter
>Man sollte besser das Overflowflag der ALU der CPU abfragen.
Aha...
Und wie geht das in C ........??
Hallo Matthias, in C geht das genauso, wie in Assembler. Normalerweise steht das Overflow Bit im Satusregister der CPU. Man kann mit C genauso auf alle Register der CPU zugreifen wie mit Assembler, so auch auf das Statusregister. Dort muss man dann nur noch prüfen, ob das OF Bit gesetzt ist. Man nenne mir den Controllertyp und ich zeig dir, wie das geht. Es kann sein, dass im Headerfile des Comlipers nicht definiert ist, wo das Statusregister liegt, das ist aber mit einer kleinen Definition erledigt. Dann kann man mit C darauf zugreifen. Beim AVR (Beispiel AtMega16) etwa so:
1 | #define SREG _SFR_IO8(0x3F)
|
2 | #define C 0
|
3 | #define Z 1
|
4 | #define N 2
|
5 | #define V 3
|
6 | #define S 4
|
7 | #define H 5
|
8 | #define T 6
|
9 | #define I 7
|
10 | |
11 | if (SREG & (1 << V)) ... //twos complement overflow occured |
12 | if (SREG & (1 << C)) ... //carry flag has been set |
Was man braucht, steht in C und V. Grüße, Peter
Das ist mir soweit bekannt, war mir nur nicht sicher, dass das in der Hochsprache C auch korrekt funktioniert...
Sowas macht man nicht! Es kann funktionieren, muss aber nicht, da der Compiler Codeblöcke umsortieren kann und somit die Abfrage möglicherweise keinen Sinn mehr ergibt, da sie an einer falschen Stelle ausgeführt wird.
Hallo, man muss sich auf jeden Fall nachher den Assemblercode davon ansehen. Wenn der Compiler das nicht so umsetzt, dass es funktioniert, muss man - ansonsten rate ich dazu, dass man - sowohl die Addition als auch die Overflowabfrage in Inlineassembler hinschreibt. Aber prinzipiell lassen sich die Satusbits auch in C abfragen und in der Regel wird der Compiler auch die Reihenfolge nicht vertauschen. Dennoch besteht die Gefahr, dass eine Optimierung dafür sorgt, dass das nicht mehr geht. Wobei ein guter Compiler auch erkennt, dass die Statusflags der letzten Operation abgefragt werden und deshalb die Reihenfolge nicht getauscht werden dürfen. Davon kann man beim gcc aber nicht ausgehen. Peter
Eleganter geht es in C, also ohne sich die Mühe machen zu müssen, den Code nachher zu prüfen, wenn man als i und iAlt 16 bit Werte nimmt und als Regelabweichung 8 bit Werte. Dann hat man dafür gesorgt, dass maximal 128 als Regelfehler auftreten kann. So kann man Grenzwerte von i angeben, ab denen man abschneidet, bei denen sicher noch kein Überlauf passiert. i = iAlt + Regelabweichung; if ((i < 32639) && (i > -32639)) iAlt = i; else i = iAlt; Wenn man aber darauf angewiesen ist, dass i und Regelabweichung vom gleichen Typ sind, sollte man tatsächlich den Overflow der ALU auswerten, andernfalls wird die Berechnung, ob ein Überlauf auftreten wird, recht aufwendig. Man müsste dazu erst ausrechnen, wieviel Platz noch in i nach oben und unten ist bis zum Überlauf und dann abfragen, ob die Regelabweichung größer ist, als dieser Wert. Das ganze mit Fallunterscheidung für positive und negative Werte. Auf DSPs hat man dieses Problem im Übrigen meist nicht, denn die meisten können saturiert addieren, d.h. das Register läuft nicht über, sondern wird nur auf den Maximalwert gesetzt, wenn man zu viel draufaddiert. Peter
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.