Hallo zusammen, ich habe folgende Unsicherheit: Ich definiere "STROM", wie folgt: #define STROM LATB,7 Um "STROM" zu verändern, habe ich die folgende Möglichkeit: banksel LATB bcf STROM banksel .0 Besser würde mir gefallen, wenn ich schreiben könnte: banksel STROM bcf STROM banksel .0 Sind beide Schreibweisen gleichwertig?
Erzeugte HEX file angucken oder den Listing file. Da siehst du was aus den konstrukten gemacht wird.
Hallo Andreas, danke für den Tipp. Das habe ich versucht, aber leider bin ich (noch) nicht in der Lage, bei MPLAB/Assembler ein Listing oder den Disassembler aufzurufen. Vielleicht weißt Du die Antwort, so dass ich weiter kommen kann? Ich wäre Dir sehr dankbar!
Problem gelöst: Die folgende Schreibweise funktioniert nicht und erzeugt eine Fehlermeldung. #define STROM LATB,7 banksel STROM bcf STROM banksel .0 D.h. der Assembler gibt die Meldung aus, "Illegal character (,)". Ich kann zwar kein Komma sehen, aber wenn das funktionieren würde, würde keine Fehlermeldung kommen. Also muss ich weiterhin schreiben: banksel LATB bcf STROM banksel .0 Danke für die Anregung, Andreas, die letztendlich zum Ziel geführt hat!
Das mit dem Komma ist schon richtig. Aus banksel STROM macht der Präprozessor banksel LATB,7 und dieses Komma sieht jetzt der Assembler und kann damit nichts anfangen. Bernd
Du musst das Teilen. #define StromPort LATB #define StromPin 7 Dann klappt
1 | banksel StromPort |
2 | bcf StromPort,StromPin |
Vorteil ist dabei das du beliebig Port und Pin ändern kannst und Banksel trotzdem stimmt. Bei deiner Methode ist Strom und Banksel entkoppelt, und wenn du mal was änderst oder einen Codeteil woanders nochmal benutzen willst knallts, weil du oben das define geändert hast, aber nicht dran gedacht das hier und da ein banksel auch angepasst werden muss.
:
Bearbeitet durch User
Hallo Bernd, herzlichen Dank für Deine Hilfe! Hierdurch ist jetzt klar, woher das Komma und die Fehlermeldung kommt. Das war mir bislang nicht klar! Michael
Hallo Jens, das ist ja toll! Es gibt also doch eine Lösung, wie ich sie am liebsten hätte! Darauf wäre ich allerdings nie alleine gekommen! Hierzu fehlt mir mindestens die Erfahrung... Das werde ich gleich einmal ausprobieren, denn genau nach dem Ändern des Portes gab es Schwierigkeiten, wie Du sie erklärt hast! Wunderbar und vielen Dank für Deine Mühe! Michael
Probier mal das hier:
1 | #define xbanksel(x,y) banksel x |
2 | |
3 | #define STROM LATB,7 |
4 | |
5 | xbanksel STROM |
6 | bcf STROM |
7 | banksel .0 |
Hallo Peter, ich kann das gerade nicht ausprobieren, aber dennoch die Fragen: "xbanksel(x,y)" ist scheinbar selbst definiert. Was bedeutet "(x,y)"? Ist "x" Platzhalter für "LATB"? Ist "y" Platzhalter für die "7"? Bei "Banksel x" ist dann "x" Platzhalter für "LATB"? Was mir sehr gut gefällt, ist, dass man dann nur noch mit dem Label "STROM" arbeitet. Die ganze Lösung ist jedenfalls - wenn sie funktioniert - äußerst raffiniert und ich frage mich, was ich tun soll, um solche Lösungen künftig selbst zu finden! Herzlichen Dank für Deine Mühe und für die Idee! Michael
Falls das der C Präprozessor ist, müsste das nicht eher so aussehen:
1 | #define xbanksel(x) xbanksel_eval(x) |
2 | #define xbanksel_eval(x,y) banksel x |
3 | #define STROM LATB,7 |
4 | xbanksel(STROM) |
5 | bcf STROM |
6 | banksel .0 |
(das xbanksel_eval, weil "STROM" erst dort aufgelöst wird, und klammern bei xbanksel(STROM), weil sonst macht das doch gar nichts).
1 | $ gcc -P - -E <<EOF |
2 | #define xbanksel(x) xbanksel_eval(x) |
3 | #define xbanksel_eval(x,y) banksel x |
4 | #define STROM LATB,7 |
5 | xbanksel(STROM) |
6 | bcf STROM |
7 | banksel .0 |
8 | EOF |
1 | banksel LATB |
2 | bcf LATB,7 |
3 | banksel .0 |
Hallo Daniel, es handelt sich um MPLAB X-IDE, Assembler für PIC16F1512, also nicht um den C-Präprozessor! Michael
Das ist nicht unbedingt ein entweder oder... https://ww1.microchip.com/downloads/en/DeviceDoc/MPLAB%20XC8%20PIC%20Assembler%20User%27s%20Guide%2050002974A.pdf > 5. Assembler Features > The PIC Assembler provided access to a **C preprocessor** and many predefined > psects and identifiers that you can use in your programs.
Hallo Daniel, danke für den Hinweis. Ich muss aber gestehen, dass dies doch über mein Verständnis weit hinaus geht. Kannst Du mir vielleicht erklären, was die folgenden beiden Zeilen bedeuten? #define xbanksel(x,y) banksel x #define STROM LATB,7 Ist es so, dass "x" ein Platzhalter für "LATB" ist und "y" für "7"? Michael
Michael B. schrieb: > #define xbanksel(x,y) banksel x > #define STROM LATB,7 > > Ist es so, dass "x" ein Platzhalter für "LATB" ist und "y" für "7"? `#define` definiert ein Macro. Macros ersetzen Text. Wenn also irgend wo im Dokument `STROM` vorkommt, wird es durch `LATB,7` ersetzt. Kommt irgend wo `xbanksel(hello, world)` vor, wird es durch `banksel hello` ersetzt (ja, x und y sind dort Platzhalter die wiederum ersetzt werden). Bei `xbanksel(STROM)` verhält es sich so, dass zuerst `xbanksel()` mit Parameter `STROM` ersetzt wird, und nicht zuerst `STROM` vor `xbanksel`. Bei der Definition oben ist das ein Argument zu wenig. Falls der Präprozessor es trotzdem zulässt, wird es mit `banksel LATB,7` ersetzt werden, (Parameter `x` ist `STROM` und wird mit `LATB,7` ersetzt). Bei meinem Macro:
1 | #define xbanksel(x) xbanksel_eval(x) |
2 | #define xbanksel_eval(x,y) banksel x |
passiert in dem fall aber folgendes. `xbanksel(STROM)` wird zu
`xbanksel_eval(LATB,7)` wird zu `banksel LATB,7`. Parameter x von
xbanksel war wieder `STROM`, wurde aber durch `LATB,7` ersetzt, bevor
`xbanksel_eval()` ausgewertet wurde, dort wurde dann also effektiv
`xbanksel_eval(LATB,7)` ersetzt, mit Parameter `x` als `LATB` und `y`
als `7`.
Das ganze funktioniert so hauptsächlich aus historischen gründen. Hatte
sich damals wohl einfach so ergeben.
Und zum schluss noch, bei:
> xbanksel STROM
Da ja xbanksel() und nicht xbanksel definiert wurde, sollte das
eigentlich nicht ersetzt werden, aber ich weiss nicht, ob alle
Präprozessoren das gleich behandeln. `STROM` würde aber trotzdem mit
`LATB,7` ersetzt.
PS: Es gibt da noch weitere Eigenheiten, und Tricks, wann was wie
ersetzt wird. Muss man einfach wissen.
:
Bearbeitet durch User
Hallo Daniel, herzlichen Dank für Deine ausführliche Erklärung und für die Zeit, die Du Dir genommen hast! Das ist ja ausgesprochen trickreich und Deine Bemerkung, dass das wohl aus "historischen Gründen" funktioniert, finde ich interessant. Gibt es eigentlich eine Textstelle, die man nachlesen könnte, um sich in diese Technik einzulesen? Als Hobbyist, habe ich einmal nachgezählt, an wieviel Stellen meines Programmes ein relozierbarer Code nützlich wäre. Ich zähle nur 10 Stellen, die man natürlich auch so beherrschen kann. Außerdem ist es so, dass ich nur einmal den Controller / die Verdrahtung gewechselt habe. In der Folgezeit wird erst mal keine weitere Änderung stattfinden. Aber darum geht es ja nicht, sondern ich vermute, dass man mit dieser Technik noch ganz andere Sachen lösen könnte. Die Arbeit mit Macros erscheint mir an dieser Stelle ausgesprochen kompliziert und man muss schon Routine haben, sich darin fehlerfrei auszukennen. Dennoch würde ich gerne hierüber etwas mehr erfahren und deshalb die Frage nach Textdokumenten, die zum Thema relozierbarer Code / Macros etwas aussagen. Michael
Daniel A. schrieb: > Das ganze funktioniert so hauptsächlich aus historischen gründen. Hatte > sich damals wohl einfach so ergeben. Das find ich interessant. Ich progge PICs schon seit 30 Jahren in Asm, aber den kannte ich noch nicht.
1 | #define xbanksel(x,y) banksel x |
2 | |
3 | #define STROM PORTA,7 |
4 | #define WASSER TRISA,2 |
5 | #define GAS BORCON,5 |
6 | |
7 | xbanksel(STROM) |
8 | bcf STROM |
9 | xbanksel(WASSER) |
10 | bsf WASSER |
11 | xbanksel(GAS) |
12 | bcf GAS |
funzt bei mir in MPLAB 8.92 mit MPASM5.51 und einem ASM-Projekt für einen PIC16F1516. Nicht wegen der Namen und Register meckern, ich hab da nur schräge Werte reingekloppt damit ich das im Disasm erkenne. Die Version mit dem eval dagegen wirft Fehler.
Jens M. schrieb: > Ich progge PICs schon seit 30 Jahren in Asm, aber den kannte ich noch > nicht. Ich habe jetzt nochmal im C Standard nachgesehen, was der dazu sagt. Ich kannte es bisher nur so wie es gcc und clang machen, aber es scheint nicht explizit definiert zu sein. Zuerst dachte ich, es wäre in https://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf Abschnitt 6.10.3 Paragraph 11, letzter Satz, beschrieben, aber dort ging es um Sachen wie `MY_MACRO(#define Y\n)`. Dazu, in welcher Reihenfolge die 2 Typen von makros ersetzt werden, scheint nichts zu stehen... Eventuell muss ich solche Sachen mal aus meinen Programmen raus nehmen. Dass es schon im Preprozessor UB drin haben könnte, auf die Idee bin ich vorher noch gar nie gekommen...
:
Bearbeitet durch User
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.