Guten Tag, bin daran, die Firmware einer feldorientierten Motorsteuerung von Microchip auf meine Bedürfnisse abzuändern. Nun stecke ich an dieser Stelle fest und komme nicht mehr weiter: #define MAX_PH_ADV_DEG 60 #define MAX_PH_ADV (int)(((float)MAX_PH_ADV_DEG / 360.0) * 65536.0) Um die Phasenverschiebung mit einem Poti zu verstellen, möchte diese zwei Definitionen, also Konstanten als Variablen umdeklarieren, etwa so: //1: int MAX_PH_ADV_DEG = 60; //2: int MAX_PH_ADV = (int)(((float)MAX_PH_ADV_DEG / 360.0) * 65536.0); Wenn ich nur die 2: als Variable deklariere, dann akzeptiert der Compiler dies. Sobald ich aber die 1: als Variable deklariere, verlangt der Compiler eine Konstante. Wie kann man die 2: ändern, so dass eine Variable akzeptiert wird? Freundliche Grüsse Jan
Niklas G. schrieb: > Jan S. schrieb: >> Wie kann man die 2: ändern, so dass eine Variable akzeptiert wird? > > C++ benutzen 😉 Das geht nicht, der Compiler für die dsPics ist sehr Prozessorspezifisch. MFG Jan
Solange in der Deklaration gerechnet werden soll, geht das nur mit Konstanten. Das wird ja bei der Übersetzung vom Präprozessor/Compiler erledigt. Sollen "lebende Werte" verwurschtelt werden, muss das zur Laufzeit erfolgen, also per Codezeile(n) innerhalb deines Programms.
Dann wirst du wohl MAX_PH_ADV in einer Initialisierungs-Funktion oder am Anfang der main() manuell berechnen & initialisieren müssen. Allerdings: Im Code wird MAX_PH_ADV_DEG überhaupt nur verwendet um MAX_PH_ADV zu initialisieren. Du könntest es auch einfach so machen (und MAX_PH_ADV_DEG ganz entfernen):
1 | int MAX_PH_ADV = 65536 / 6; |
Und dann MAX_PH_ADV direkt per Poti modifizieren. Braucht dann auch keine float-Berechnung.
:
Bearbeitet durch User
Horst V. schrieb: > Solange in der Deklaration gerechnet werden soll, geht das nur mit > Konstanten. Das wird ja bei der Übersetzung vom Präprozessor/Compiler > erledigt. Sollen "lebende Werte" verwurschtelt werden, muss das zur > Laufzeit erfolgen, also per Codezeile(n) innerhalb deines Programms. Danke für die Antwort, werde versuchen, den Codeschnipsel weiter unten einzufügen. MFG Jan @ Niklas: Danke, werde ich versuchen, float braucht es aber vermutlich, weil der ADC fraktional ausgelesen wird. MFG Jan
Jan S. schrieb: > float braucht es aber vermutlich, > weil der ADC fraktional ausgelesen wird. Wäre das nicht eher Fixed-Point?
Niklas G. schrieb: > Jan S. schrieb: >> float braucht es aber vermutlich, >> weil der ADC fraktional ausgelesen wird. > > Wäre das nicht eher Fixed-Point? Das ADC Ergebnisregister liefert das Ergebnis "big endian" (sagt man, glaub ich), also linksseitig. Später wird der Wert als "signed" gehandelt, um vorwärts- bzw. Rückwärtsbetrieb zu generieren, aber ich blicke da noch nicht ganz durch.
Jan S. schrieb: > Guten Tag, > bin daran, die Firmware einer feldorientierten Motorsteuerung von > Microchip auf meine Bedürfnisse abzuändern. > Nun stecke ich an dieser Stelle fest und komme nicht mehr weiter: > > #define MAX_PH_ADV_DEG 60 > #define MAX_PH_ADV (int)(((float)MAX_PH_ADV_DEG / 360.0) * 65536.0) Warum? Oliver
Ich würde beides durch eine Funktion ersetzten. Etwa so:
1 | int max_ph_adv(float max_ph_adv_deg) { |
2 | return max_ph_adv_deg/360.0*65536.0 |
3 | }
|
Dann ist auch transparent, dass die Berechnung für jeden Wert von max_ph_adv_deg erneut stattfinden muss.
Jan S. schrieb: > Das ADC Ergebnisregister liefert das Ergebnis "big endian" (sagt man, > glaub ich), also linksseitig. Das kann dem Prozessor ziemlich wurscht sein, weil der ja wohl hoffentlich die gleiche Byte-Reihenfolge wie die Peripherie nutzt. Jan S. schrieb: > Später wird der Wert als "signed" gehandelt, um vorwärts- bzw. > Rückwärtsbetrieb zu generieren, Das hat dann aber immer noch nichts mit Float zu tun. Steve van de Grens schrieb: > Ich würde beides durch eine Funktion ersetzten. Ich würde mir die wiederholte float-Berechnung ganz sparen. Lieber das MAX_PH_ADV mittels Poti um Integer-Werte inkrementieren / dekrementieren.
Steve van de Grens schrieb: > Ich würde beides durch eine Funktion ersetzten. Etwa so: > int max_ph_adv(float max_ph_adv_deg) { > return max_ph_adv_deg/360.0*65536.0 > } > > Dann ist auch transparent, dass die Berechnung für jeden Wert von > max_ph_adv_deg erneut stattfinden muss. Danke für Deinen Vorschlag, auch das werde ich probieren. MFG Jan
Sodele, jetzt wird regelmässig eine Funktion per polling aufgerufen und es funzt. Vielen Dank für die inputs. Mfg Jan
Jan S. schrieb: > Sodele, jetzt wird regelmässig eine Funktion per polling aufgerufen und > es funzt. Und wir haben grad erst MO... Ja, wenn dein Controller sonst nix zu tun hat, kann man das gern so machen. Aber überleg dir lieber mal ob du es nicht durch Interrupt oder PDC / DMA oder sonst was lösen möchtest. Also ich könnte da net ruhig schlafen, wenn das so "dirty" gelöst ist. Jeder Function-Call kostet zeit. Kann man sich sparen. edit: Im besten Fall machst dir ein klein Scheduler der Events von Interrupts entgegennimmt und dann die dazugehörige Funktion aufruft. Nur so mal als Idee. Klar, für kleine Systeme voll Overplay, aber wenn man es einmal hat, will man net mehr drauf verzichten. (eigene Erfahrung)
:
Bearbeitet durch User
Adam P. schrieb: > Ja, wenn dein Controller sonst nix zu tun hat, kann man das gern so > machen. > Aber überleg dir lieber mal ob du es nicht durch Interrupt oder PDC / > DMA oder sonst was lösen möchtest. Vielen Dank für den Input. Das mit dem Interrupt habe ich mir schon überlegt, da aber die von mir veränderte Originalfirmware sowieso in einer Endlosschlaufe eine Taste zum ein/ausschalten pollt, polle ich als Minimalist gleich noch einen anderen Pin. In erster Linie gehts mir darum, den Unterschied der Drehzahl des Motors zu ermitteln, wenn Phaseadvance auf dem Maximum ist. Die ganze Schaltung habe ich mit der Absicht aufgebaut, einen Einblick in die feldorientierte Motorsteuerung zu erhalten. Freundliche Grüsse Jan
:
Bearbeitet durch User
So könnte man alle glücklich machen :
1 | //0:
|
2 | #define MY_MAX_PH_ADV_DEG 60
|
3 | //1:
|
4 | int MAX_PH_ADV_DEG = MY_MAX_PH_ADV_DEG; |
5 | //2:
|
6 | int MAX_PH_ADV = (int)(((float)MY_MAX_PH_ADV_DEG / 360.0) * 65536.0); |
Der gewünschte Startwert müsste dann bei 0 eingetragen werden. Wenn man eine Variable davon im Laufe der Programmausführung ändert, sollte man die andere am Besten mit anpassen, sonst kommt man aus dem Staunen über die Ergebnisse vermutlich nicht heraus. :-P
Flunder schrieb: > So könnte man alle glücklich machen : Wenn jetzt noch darauf verzichtet würde, die Konvention zu ignorieren, daß nur Macros (#defines) in VERSALIEN geschrieben werden, dann würde die Zahl der Glücklichen steigen.
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.