Hallo zusammen,
derzeit versuche ich mich an relocatable code. Ich verwende MPLAB 8.9. Dazu habe ich im Projekt 2 ASM-Files angelegt:
1. Main.ASM - verwendet z. LCD_Init, LCD-Ausgabe aus File 2
2. LCD_Lib.ASM -verwendet Variablen und Labels aus File 1
In beiden Dateien werden mit GLOBAL und EXTERN bezeichnete Variablen und Subroutinen verwendet. Die Subroutinen in LCD_Lib.ASM können aus Main.ASM heraus problemlos aufgerufen werden, ebenso wie die Verwendung gemeinsam genutzer Variablen (GLOBAL, EXTERN). Das funktioniert.
Das Prinzip: Um die Verwendung verschiedener PIC's zu erleichetern, da ich den Programmcode so mit geringstmöglichen Änderungen weiterverwenden kann, verwende ich für PORTS und auch für Pins Platzhalter, also Labels in dieser Form:
LED_PORT EQU PORTA
LCD_LAT EQU LATA
usw...
LCD_DAT EQU RA0 (ich verwende bevorzugt mein 2Wire-Interface)
LCD_CLK EQU RA1
LED EQU RA2
#DEFINE LED_ON bsf LCD_PORT,LED
Das Problem: Wie kann ich diese Lables LCD... in beiden ASM-Files gleichermaßen verwenden?
Im File LCD_Lib.ASM werden diese Labels als ungülti bezeichnet, da diese erneut definiert werden un das nicht zulässig ist. Ichfinde nichts, was mir da weiterhilft.
Frage: Wie erreiche ich, daß ein in Main.ASM zugewisern Label auch in LCD_Lib.ASM verwendet werden kann?
Freue mich auf hilfreiche Antworten!
mfG Ottmar
Ich hatte mir eine Datei angelegt wo die konfig enthalten war. Diese habe ich in allen Dateien per include eingefügt. Im der Datei war z.b. die inc Datei des Pics, Pic Taktfrequenz, Bus Geschwindigkeit usw. Zumindest konnte ich so durch einmaliges festlegen es in mehreren Dateien nutzen. Eine andere Möglichkeit habe ich nicht hingekriegt.
Sonniger Gruß aus Spanien (Urlaub)
Cobra
@Cobra
Wenn ich mit den genannten ASM-Files alle Labels so wie vorstehend weglasse und nur mit Variablen und Subs arbeite, klappt alles wunderbar!
Ah! O:-) Die Erleuchtung! Ich verstehe! Diese Labels sind kein Variablen, keine Subroutine und müssen also gleichermaßen in beiden Dateien vorhanden sein,wie z.B. #INCLUDE <P18F14K22.INC> welches ich ja bereits in 1+2 eingschlossen habe! Der Inhalt sind auch alles Labels!
Jaaaa! Dann brauche ich ja nur dieses eine prozessorspezische #include 18F14K22_LCD_2Wire.INC in1+2 einzufügen
Das probiere ich gleich aus, bin gespannt!
Wenn's klappt, warst Du es, der mir auf das richtige Pferd geholfen hat!
na dann - schönen Urlaub! Hier im Schwabenland herrscht Sauwetter!
mfG Ottmar
das müsste auch mit "extern" gehen. In der einen Datei unter global definieren, in der anderen mit extern definieren. Ich habe irgendwo auf der Festplatte solch selbst geschriebenen Dateien hier greife ich mit C auf Assembler Variablen zu.
Ich hatte hier schon einmal eine Interrupt Routine hochgeladen, da hatte ich Variablen mit extern und global definiert.
https://www.pic-microcontroller.de/dlattach/?attach=2874
Danke für die Rückmeldungen!
Danke PIC18 für den Hinweis auf Deine Datei-Vorlage!
Damit meine ich ist aber der Problempunkt nicht getroffen. Wie in meinem 2.Post mitgeteilt, funktioniert ja bereits in beiden ASM-Files die Verwendung von gemeinsam genutzten Variablen, und Subroutinen perfekt, da diese entsprechend mit GLOBAL und EXTERN deklariert sind. Das klappt alles!
Es ging nir nur um LABEL, sowie mitgeteilt z.B. Deklaration in MAain.ASM
LCD_PORT EQU PORTA.
LCD_CLK EQU RA0
Beim Aufruf in LCD_Lib.ASM ->
bsf LCD_LAT, LCD_CLK
etc erzeugt dies eine Fehlermeldung, daß gleiche Labels nicht erneut definiert werden dürfen. Mal sehen, bin gerade dabei die Dateien umzubauen und die Labels als include-file in beide ASM-Files einzufügen.
Danke einstweilen!
Stand der Dinge:
Nachdem wie von Cobra angeregt, ich den relocatable Code zuächst mal für den 16F628 ERFOLGREICH umgesetzt habe, wurde ich mit ERFOLG belohnt.
1. File 'Main.ASM" wurden sämliche Deklarationen von Labels (#define, equ) DIREKT nach dem CONFIG-WORD angeordnet
2. im File "LCD_Lib.ASM" wurde sämtliche Deklaration von Labels DIREKKTl nach " #INCLUDE <p16F628A.inc> angeordnet.
Nachdem der Code mittels Pickit3 auf den PIC übertragen war, lief alles reibungslos!
Danke an alle, besonders an Cobra!
Ottmar
Hallo,
melde mich nochmals abschließend zu "Relocatabe Code"
Wäre das Wissen um nachstehenden Sachverhalt früher für mich verfügbar gewesen, ja dann hätte ich es oft weniger schwer gehabt in der Handhabun von umfangreicherem "Relocatable Code"!
inzwischen habe ich noch einiges an Erfahrung gesammelt - was den Umgang mir "Relocatable Code" betrifft. Es hat sich gezeigt,. daß es (fast) ziemlich einfach ist - ja, wenn man weiß wie!.
Es gilt nur einige Grundregeln zu beachten. Z.B. besteht ein Projekt aus diesen Dateien:
Source Files
18F14K22_Main_LCD_2_Wire.ASM ;Prozessor declaration + Main + ISR_H igh + ISR_Low
HD44780_LCD_2Wire_Init.ASM ;Lcd-Initialisierung + zugehörige Subroutinen
HD44780_LCD_Subroutinen.ASM ;Alle anderen Subroutinen zum LCD-Handling
Header Files
p18F14k22.INC ;muss in jedes ASM-File mit include eingefügt sein.
18F14K22_LCD_2wire_HEADER.INC ; CONFIG-Bits, Labels&Constants
18F14K22_Lcd_2wire_INIT.INC ;Initialisierung PORTs, SFR, Interrupt usw
HD44780<_Labels.INC ;Stets mit LCD verwendete Labels & Constants
Subroutinen GLOBAL und EXTERN
In jedem ASM-File werden Subroutinen welche von anderen ASM-Files verwendet werden als GLOBAL bezeichnet, z.B.:
GLOBAL Lcd_Init,
GLOBAL LcdOut_Data)
Diese Dateien können in einem Rutsch in das ASM-File kopiert, dort als EXTERN bezeichnet und auch aufgerufen werden, z.B.:
EXTERN Lcd_Init
EXTERN LcdOut_Data
Variable GLOBAL und EXTERN
In gleicher Weise verfährt man mit Variablen, welche zum Aufruf einer Subroutine bnötigt werden, z.B.:
An die Sub "LcdOut_Table", deklariert in "HD44780_Output_Subroutines.ASM", muß der H-und Low-Pointer auf eine "LookUp-Tabelle ( LUT) übergeben werden.
Diese Sub wird in der Datei "18F14K22_LCD_2wire.ASM" aufgerufen und dazu die pointerH:L übergeben. Zuvor jedoch müssen vor Aufruf der Sub die Übergabevariablen in beiden Dateien entsprechend deklariert sein. Z.B.:
GLOBAL pointerH, pointerL in "HD44780_Output_Subroutines.ASM"
EXTERN pointerH, pointerL in "18F14K22_LCD_2wire.ASM"
Natürlich müssen in jedem ASM-File die dort verwendeten Variablen deklariert und mit Speicherplatzbedarf bezeichnet sein. Z.B:
LOC_VAR UDATA
LcdCtrl RES 1 ;Speicherbedarf: 1Byte
ACb RES 2 ;16Bit-Zahl (->ACb+0, ACb+1)
Werden Variable im Programmspeicher per FSR ausgelesen/beschrieben, ist es praktisch wenn diese in aufsteigender Reihenfolge im Flash angeordnet sind. Dies erreicht man, indem zusätzlich noch die Startadresse angegeben wird, wobei "FSR_VAR" frei wählbar ist, UDATA aber eime Pflichtangabe ist.
FSR_VAR UDATA 0x60
BCD4 RES 1 ;global Result 10thousands
BCD3 RES 1 ; thousands
BCD2 RES 1 ; hundreds
BCD1 RES 1 ; tens
BCD4 befindet sich dann an Adresse 0x60 und BCD1 an Adresse 0x64.
Im Zweifelsfall kann alles zu diesem Thema nachgelesen werden: Microchiip-Druckschrift DS33014L MPASM™ Assembler, MPLINK™ Object Linker....
mfG Ottmar
Extern und Global ist klar, hatte ich oben schon beschrieben. Die Zuweisung FSR habe ich nicht verstanden. Es gibt ja hier auch mehrere FSR0 .. FSR2. Hier arbeite ich mit POSTINC, POSTDEC, INDF PLUSW usw. Das benutze ich hauptsächlich um ein Assemblerprog., von C aufzurufen und die Parameter zu übergeben.
Mit "FSR" meine ich allgemein "File Select Register",klar, dass die entsprechend vorgesehenen Mnemonics FSR0H;L etc verwendet werden um den Inhalt von Adressen auszulesen/zu beschreiben. Wollte nur sagen, sollte eine Folge von Variablen ausgelesen/beschrieben werden, dass dann nach UDATA der Speicherbeginn angegeben werden sollt, damit die Variablen vom Linker auch wirklich in Folge abgelegt werden.
Interessant ist auch, dass ich manche Zuweisungen nur dann hinbekommen habe, wenn für die ensprechende Variable unter
TEST_VAR UDATA_ACS
Test RES 1
Speicherplatz zugewiesen worden ist.