Forum: Mikrocontroller und Digitale Elektronik PIC: Benneung des RAM


von Bernd D. (bernddoe)


Lesenswert?

Ich programmiere einen PIC 18F2321 mit dem MPLAB IDE v8.02.
Wenn ich den mitgelieferten inc- Datei einbinde werden unter anderen die 
ersten 8 RAM Speicheradressen und etliche ander mit Namen aus der 
Bit-Definition diverser Register belegt (z.B. ADCS1 auf RAM-Speicher 
0x002). Da die ganzen Bit's mit EQU definiert werden ist das soweit auch 
logisch, denn der Assembler fasst das als Speicheradresse auf.

Aber welchen Sinn macht das? Warum werden die Bit's nicht mit #define 
zugewiesen? Dann wird beim builden der Bit-Name durch die Zahl ersetzt, 
und das wars.

Oder kann das durch durch einen Compilerbefehl verhindert werden?
Oder muß ich eine spezielle Datei im Linker einbinden?

Hat jemand eine Ahnung zu dem Problem?

Gruß

Bernd

von Andreas K. (a-k)


Lesenswert?

Du wirfst da einen Haufen Begriffe in einen Topf die nicht wirklich 
zusammenpassen.

"inc" Files gehören zu Assemblern, Compilerbefehle zu Compilern. 
Assembler sind keine Compiler und Compiler keine Assembler.

Die unteren Adressen in dem was du RAM nennst sind kein RAM sondern 
allerlei Steuerregister, I/O-Ports usw, die lediglich auf die gleiche 
Weise adressiert werden wie das RAM.

Manche Assembler arbeiten mit dem C-Präprozessor (GCC, AVR), andere 
nicht. Wenn ein Assembler nicht mit dem Präprozessor arbeitet, nützt dir 
#define nichts.

von Bernd D. (bernddoe)


Lesenswert?

Gut, die Kritik ist berechtigt. Ich versuche präziser zu sein:

Ich erstelle ein Programm in Assembler im MPLAB IDE v8.02. Dort gibt es 
die Assembler-Anweisung include, um eine von Microchip mitgelieferte 
Datei mit Standarddefinitionen einzubinden.

In der Datei sind mit EQU die Hex-Adressen der Steuerregister auf 
Klarnamen umgesetzt. Ebenso sind dort, ebenfalls mit EQU, die 
Bit-Bitbezeichnungen, wie im Datenblatt angegeben, auf die Bit-Nummer 
gesetzt. Zusätzlich sind einige Kombinationen als höhere Werte 
vordefiniert.

Die EQU-Anweisung weist einem String einen Wert zu, und das wird wohl 
vom Assembler oder dem Simulator immer als Zuweisung einer RAM Adresse 
verstanden.

Das RAM der PIC setzt sich aus den Funktionsregistern und allgemeinen 
Registern zusammen. Letztere sollten nach meinem Verständniss bei einem 
leeren Programm im Fenster "File Register" des Simulators leer d.h. ohne 
Namen sein. Und genau das sind sie nicht, sondern es wird z.B. ADCS1 als 
Variable mit Adresse 0x001 angezeigt. In der Definition ist es mit 
"ADCS1 EQU 0x001" mit der Bedeutung "Bit1 des Registers ADCON2" 
definiert.
Ob das jetzt physikalisch ein RAM oder sonst was ist sollte im Simulator 
erst mal keine Rolle spielen. Das Datenblatt spricht jedenfalls von 
"static RAM".

Wenn ich die EQU-Anweisungen durch #define ersetze kommt es nicht zur 
Zuweisung der Variablen. Ich unterstelle mal, das Microchip sich was bei 
der Erstellung der Datei gedacht hat. Nur was?

Die Frage ist also:
Gibt es eine Assembler-Anweisung, die das verhindert?
Oder kann das durch ein Linker-Skript verhindert werden? Ich verwende 
nur eine .ASM Datei und linke keine weiteren Dateien ein.

Oder was?

von Sven S. (stepp64) Benutzerseite


Lesenswert?

Dieser "Fehler" ist mir auch schon mal aufgefallen. Allerdings stört er 
nur bei der Anzeige im Simulator. Du kannst durchaus auf die Adresse 8 
(oder einer anderen vermeintlich schon belegten Adresse) deine eigene 
Variable legen indem die diese Adresse halt neu vergibst. Laut 
Datenblatt fangen die Special Function Register (SFR) ja erst bei H60 
an. Der freie RAM fängt bei H0 an. Somit ist die Anzeige im Simulator 
falsch.

Die EQU Anweisung weist auch noch nicht den RAM direkt zu. Vielmehr sagt 
sie dem Assembler/Compiler das ab sofort jedes mal wenn im Quelltext der 
Name auftaucht, der zugewiesene Wert zu ersetzen ist. Bsp:

Test1      equ     0x22
movlw      0x10
movwf      Test1

movlw      Test1        ;hier wird nach w 0x22 geladen
movfw      Test1        ;hier wird nach w 0x10 geladen (der Inhalt von 
0x22)

Du musst dir Einfach vorstellen, dass statt Test1 eine 0x22 im Quellcode 
steht und das ist das auch verständlich.

Was jetzt allerdings genau #define macht und wann man was benutzt, kann 
ich nicht genau sagen. Hab mich allerdings auch schon gefragt warum es 
da Unterschiede gibt.

Sven

von Bernd D. (bernddoe)


Lesenswert?

So hatte ich das auch verstanden. Verwirrend ist es aber schon.
Was dazu kommt: Wenn ich nach der Include Anweisung mit "CBLOCK" die 
Variablen benenne werden die Namen aus der INC-Datei in der Anzeige der 
Register nicht überschrieben, aber - wie Sven  beschreibt - geändert, 
wenn ich auf die neuen Namen mit z.B. MOVWF zugreife.

Das Problem macht halt das Leben nicht gerade einfacher, denn auch in 
dem Watch-Fenster etc. kann ich die Variable nicht unter dem korrekten 
Namen sehen sondern nur unter dem falschen.

Ich habe jetzt erst mal die ganzen Definitionen durch #define ersetzt, 
damit funktioniert es. Denn die Alternative, die Register nicht zu 
benutzen, ist auch nicht so prickelnd.

Bernd

von tastendrücker (Gast)


Lesenswert?

EQU:
Assembler Konstante. Kann nur einmal gesetzt werden (deswegen wird in 
den Include Dateien EQU verwendet)

PORTA EQU 0x10
PORTA EQU 0x20  <- Erzeugt Assenbler-Error


SET:
Assembler Variable. Kann mehrfach gesetzt werden.

A1 SET 0x10 ; weist der Variablen A1 den Wert 0x10 zu
A1 SET 0x20 ; weist der Variablen A1 den Wert 0x20 zu (kein Error!)


#define:
Textersetzung.

#define pi 3.14
#define durchmesser 10.5
#define umfang durchmesser*pi

---------------
Beispiel:

PORTA EQU 0x10
BIT1  EQU 1

#define LED_AN    bsf PORTA,BIT1
#define LED_AUSN  bcf PORTA,BIT1

:
:
    LED_AN     ; POWER LED an
:
:

von Bernd D. (bernddoe)


Lesenswert?

Soweit So gut. Wenn in der Include-Datei EQU verwendet wird kann die 
Variable nicht umdefiniert werden, was das ganze sicherer macht.

Nach meinem Verständniss erzeugt der Assembler z.B. aus dem Befehl

movwf Variable

immer den gleichen Code, egal ob ich vorher schreibe

Variable EQU 0x04
Variable SET 0x04
#define Variable 0x04

In jedem Fall wir "Variable" durch 0x04 ersetzt. Aber nur bei den ersten 
beiden Definitionen erscheint im Fenster "File Register" an der Stelle 
0x04 "Variable" als symbolischer Name.

Wie kann ich aber dem Assembler klar machen, dass Variable kein Register 
ist ,sondern z.B. eine Bit-Nummer für den Befehl

bsf xxx,Variable

Villeicht kennt jemand auch das Problem

Bernd

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
Noch kein Account? Hier anmelden.