Hallo zusammen,
ich habe heute einen PID Regler in Assembler realisiert. Wenn ich die
Funktion aber aufrufe läuft alles mögliche schief, was mit der Funktion
nichts zu tun hat. Z.B. ist der UART dauerhaft am Senden. Die Funktion
wird zwar bis zum Ende hin ausgeführt, dannach fängt sie aber sofort
wieder von vorne an, anstatt im Hauptprogramm weiter zu machen.
Das ganze läuft auf einem Atmega8 auf dem ASURO.
Bevor ich jetzt einzelne Codeschnipsel poste, lade ich einfach die
relevanten Dateien hoch.
Ich hab mit Assembler leider noch nicht so viel Erfahrung und finde den
Fehler nicht.
Ist bestimmt was total triviales...
Kann bitte mal jemand drüber schauen? Ich komm einfach nicht drauf.
Vielen Dank im Vorraus
Ohne den Code jetzt angeschaut zu haben... Eine Programm Entwicklung
muss mit Fehlersuche als Konzept mit eingebaut begonnen werden. Ein
Profi weiss schon welche Fehler zu erwarten sind und hat daher schon
Testpunkte auf der Hardware eingebaut.
Ob man das nun hat oder auch nicht hat, muss man ein Mimimum zum Laufen
kriegen. zB ein UART. Oder einen Pin. Ich verwende beides. Bei schnellen
Systemen, wo das UART nicht mehr reicht, kann man auch auch einen DAC
aufstecken und mit einem Scope den Ablauf der Werte anschauen.
Aeh. Ja. Viel Glueck. Ich mag grad nichts entzippen.
Siebzehn und Fuenfzehn schrieb:> Ob man das nun hat oder auch nicht hat, muss man ein Mimimum zum Laufen> kriegen. zB ein UART. Oder einen Pin.
Das Minimum läuft alles. Es ist auch nicht so das ich Probleme habe den
UART zu verwenden oder ähnliches. Auch habe ich nicht einfach die
Fehlersuche aus der Hand gegeben, sondern selbst getestet, wie weit er
im Quellcode kommt und ähnliches.
Zum Problem UART. Wenn ich den Funktionsaufruf auskommentiere läuft er
einwandfrei. In dem Fall nämlich garnicht. Verwende ich die Funktion
dreht er am Rad, OBWOHL! er eigntlich auch hier nicht verwendet wird.
Er bekommt von mir nie an irgendeiner Stelle gesagt, dass er senden
soll.
Siebzehn und Fuenfzehn schrieb:> Ich mag grad nichts entzippen.
Auch dafür gibt es eine Lösung ;) Sieht nach viel aus, ist aber mehr
oder weniger genau das Selbe 4x.
Der Vorteil des bestehenden Codes ist dass er zeitlos und fast
unabhangeig ist. Und man so jeden Summand einzeln bearbeiten kann. Also
einen Wert (Byte, Word, Integer) ueber's UART reinschicken,
durchrechnen, und ueber's UART zurueck.
Eine Idee. Es laeuft einiges ueber den Stack. Wie gros ist der Stack ?
Der Stack ist ziemlich leer. Der aufruf der Funktion ist aus dem
Hauptprogramm und an der stelle ist der Stack schön wieder abgebaut.
Überschneidet sich irgendewas mit den von mir gewählten Adressen für
meine Variablen?
Wie wäre es wenn du systematisch ans Debuggen rangehst anstatt uns
wahllos potentielle Fehlerstellen anzubieten die wir sowieso nicht
verstehen weil wir deinen Code nicht kennen?
Um Himmels willen - wenn du da jemals durchblickst, gratuliere ich dir
herzlich. Wir haben aber keine Ahnung, was du eigentlich erreichen
willst, und welches die Stell- und Eingangsgrössen sind.
Ist Assembler hier unbedingt nötig? Es gibt so gut funktionierende und
schnelle PID Regler für die AVRs, das ich vermutlich nicht auf die Idee
kommen würde, so etwas in ASM zu realisieren. Die Wartbarkeit ist
gegenüber dem Geschwindigkeitsvorteil doch meistens wichtiger.
@Bastian
Ich weiß ja nicht mit welchem Programm du Schreibst.
Bei mir AVR 4.19 musste ich die .include in einem anderem Ort
Positionieren damit mir AVR überhaupt ohne Fehler das Programm
Simulieren lies.
Beim PID Abschnitt läuft der Stack über und das Programm läuft im
Anschluss Amok.
Schau dir noch mal den Abschnitt PID an und ich glaube bin aber nicht
sicher es liegt an den ST LD Befehlen.
Am Anfang Sicherst du die Register welche aber im Ablauf vom PID Teils
Überschrieben werden.
@Matthias Sch.
Bin im Moment auch auf der Suche nach einem PID vorzugsweise in
Assembler.
Kannst du mir aber einen Übersichtlichen und leicht Verständlichen in C
Empfehlen?
Man kann schon mit ASM arbeiten. Muss dann aber die Funktionen
entkoppeln. Dann kann man die jeweilige Funktionalitaet mit dem
Simulator testen. Wobei die Interrupt proceduren in System getestet
werden muessen - einmal.
Dann muss man auch der Uebersichtlichkeit wegen mit einer
Zustandsmaschine arbeiten. Dh der gesammte Code muss nicht blockierend
geschrieben werden. Gewartet wird genau an einer Stelle im Main(). Dort
kann man dann falls spaeter erwuenscht auch einen Sleep einwerfen.
Man darf das in jeder beliebigen Sprache machen, aber man sollte sein
Werkzeug auch danach auswählen, daß man es im Griff hat. Kompliziertes
Werkzeug nur wenn es einen Mehrwert bringt. Und sei's nur der, daß es in
C schon verfügbar ist.
Danke für den Link.
Leider hab ich um erlich zu sein mit C überhaupt keine Erfahrung.
Das restliche Programm ist in Assembler geschrieben.
Man kann ja ein Programm mit beide Sprachen schreiben nicht?
Ich verwende AVR 4.19.
Thomas Gruber schrieb:> Leider hab ich um erlich zu sein mit C überhaupt keine Erfahrung.> Man kann ja ein Programm mit beide Sprachen schreiben nicht?
Man kann in C Programmstückchen in Assembler einbinden. Umgekehrt ist
das evtl. auch möglich, habe ich aber noch nie gemacht, weil ich es
nicht brauche - denn nur ganz zeitkritische Sachen oder Mini-Programme
mache ich heute noch in Assembler. Mixen ist für dich vermutlich zu
kompliziert, weil du dann erstmal C pauken müsstest und dann noch die
Feinheiten des Einbindens.
AVR-gcc produziert so schnellen Code, das ich Assembler nicht vermisse
und die Wartbarkeit ist einfach viel besser.
Geh doch mal AVR221 Stück für Stück durch und portiere die Sachen, die
du kapiert hast in Assembler. Du wirst ein wenig 16bit Arithmetik
brauchen und eine universelle (und wasserdichte) 16bit
Multiplikationsroutine.
Wenn du das modular anlegst mit definierten Übergabeparametern, hast du
was für deine Bibliothek.