Hallo,
bin nach tagelanger Fehlersuche in einem PIC-Assemblerprogramm über
folgendes Problem gestolpert, was auch die Ursache für das Fehlverhalten
des Programm's war:
Ich hatte versehentlich ein Register doppelt definiert, d.h. ich habe
zwei Symbolnamen die gleiche Registeradresse zugewiesen. Dummerweise
meckert MPASM nicht, wenn Register doppelt definiert werden.
Gibt es neben EQU eine Lösung, mit der ich Register eindeutig definieren
kann, so daß sie sich z.B. von Konstanten unterscheiden ? Das
Voranstellen von K_ oder R_ wäre zwar eine Lösung, aber das interessiert
den Kompiler nicht wirklich.
Danke.
Und wie würde man das mit dem Errorlevel steuern?
Bin nämlich auch an einer Lösung interessiert.
Vorerst fällt mir nur der Weg ein, die Adressen der Register nicht
selber zu vergeben, sondern CBLOCK zu verwenden.
Aber absolute Sicherheit erreicht man auch dadurch nicht.
Das Problem besteht doch darin, dass man MPASM nicht verbindlich sagen
kann, dass man File Register meint, und nicht irgend eine Konstante.
Es gibt ja verschiedene Wege, ein Symbol zu definieren:
#define
EQU
SET
CONSTANT
VARIABLE
(sonst noch welche?)
>Vorerst fällt mir nur der Weg ein, die Adressen der Register nicht>selber zu vergeben, sondern CBLOCK zu verwenden.>Aber absolute Sicherheit erreicht man auch dadurch nicht.
Wieso nicht?
Automatismen zur Variablenvergabe sind mit Vorsicht zu genießen. Da z.B.
im PIC nicht alle Register direkt erreichbar sind, können automisch
erzeugte Bankumschaltungen, im Falle von Interrupts, zu erheblichen
Problemen führen.
nummernschalter wrote:
> Automatismen zur Variablenvergabe sind mit Vorsicht zu genießen. Da z.B.> im PIC nicht alle Register direkt erreichbar sind, können automisch> erzeugte Bankumschaltungen, im Falle von Interrupts, zu erheblichen> Problemen führen.
Das Problem hast Du aber ohnehin, auch wenn Du die Register einzeln
definierst.
Und bei einem Interrupt sollte man ohnehin STATUS sichern.
Ich dache eher an so etwas:
cblock 0x20
aa
bb
cc
dd
ee
ff
gg
hh
endc
cblock 0x22
xx
yy
endc
cc und xx haben beide den Wert 0x22,
dd und yy den Wert 0x23.
vielleicht hilft das ja weiter:
VARIABLE COM=h'0c' ;
variable1 equ COM ;
COM++ ;
variable2 equ COM ;
COM++ ;
usw...
so lassen sich ganze blöcke verschieben und auch vermeiden das durch
eine doppelbenennung fehler auftreten...
m.
Mhm, verstehe. So wird jedem Symbolnamen ein eindeutiger Wert
zugewiesen, wenn man nur EIN cblock-Konstrukt verwendet und sich auf
Register beschränkt. Danke, das ist eine gute Idee.
> Automatismen zur Variablenvergabe sind mit Vorsicht zu genießen. Da z.B.>im PIC nicht alle Register direkt erreichbar sind, können automisch>erzeugte Bankumschaltungen, im Falle von Interrupts, zu erheblichen>Problemen führen.
deswegen kann man solch kritische Variablen auf einen Registersatz
legen, die von jeder Bank aus erreichbar sind - bei PIC16F871 ist es
z.B. 0x70-0x7F (weiß nicht, ob dies für alle PIC16 gilt). Dafür kannste
ja einen zweiten CBLOCK definieren, womit sichergestellt ist, daß diese
kritischen Variablen auch wirklich dort sind. Für meinen Begriff schon
recht sicher (wenn man nicht aus Versehen zuviele Variablen da
reinstopft), und für das Initialproblem sicher genug.
Übrigens - meckert ein C-Compiler, wenn ich zwei Variablen denselben
Wert zuweise (zwei Pointer mit dem selben Wert z.B.)? Für den
Compiler/Assembler ist es doch nur ein (Hex-) Wert. Der Compiler weiß
doch nicht, was man damit anstellen will, und somit ist es dem doch
egal, ob damit daselbe Objekt referenziert wird.
Jedes Teil für seinen Zweck !
An PIC's gefällt mir der geringe Befehlsumfang, auch wenn ich den einen
oder anderen Befehl (z.B. direktes Kopieren von Register zu Register)
vermisse. Aber zum Glück gibt es ja Makros !
Hier nochmal so was ähnliches wie von Maddin
aa equ 0x10 ;Anfangsadresse Speicherbereich
bb equ aa+1 ;bb beginnt auf Adresse 11, für aa ist 1 Byte reserviert
cc equ bb+2 ;cc beginnt auf Adresse 13, für bb sind 2 Byte reserviert
usw.
Das blöde daran ist, dass die Anzahl der Bytes nicht hinter dem Namen
steht sondern erst in der nächsten Zeile.