Hallo, auf ein neues
Habe Problem Sprungtabelle in Externer ASM Datei
1
movf STATE,w
2
addwf PCL,f
3
goto ReadBit_01
4
goto ReadBit_02
5
goto ReadBit_03
6
goto ReadBit_04
7
goto ReadBit_05
Laut Disassembly beginnt der Code an 44A. Das Programm springt aber
immer in einen Adressen Bereich von 000 bis 0FF je nachdem was in
"STATE" steht, was aber nicht korrekt ist. Sollte doch nach 44B + STATE
springen.
Sobald der Code im Adressen Bereich von 000 bis 0FF steht, funktioniert
es.
Gruß Siegfried
Hallo Flo,
woher weis ich aber, das der Compiler dieses ab in Adresse 4XX legt ?
wenn ich vor diesem Code noche einige Zeilen hinzufüge, dann kann es
durchaus sein das dann der Code im Adressen Bereich 5XX landet.
Gruß Siegfried
Indem du ein ORG 4xx davor schreibst. Ist sowieso sicherer, damit der
Compiler den Code nicht an eine 0xFF Grenze legt. Das Ganze funzt
nämlich nur wenn du innerhalb eines Segmentes liegst, da du mit AddWf
nur 8 Bit addieren kannst.
Torsten
:Edit
Flo war schneller
Siegfried Saueressig schrieb:> woher weis ich aber, das der Compiler dieses ab in Adresse 4XX legt ?
Mußt du ja nicht wissen. Du kannst auch den Assembler rechnen lassen.
z.b. mit 2 Macros und einem Label vor Deiner Tabelle.
Das Makro P_SELW (vor Deiner Tabelle) rechnet den Wert für PCLATH aus:
1
P_SELW macro Label
2
movlw high Label
3
movwf PCLATH
4
endm
1
P_SELW Label
2
3
movf STATE,w
4
addwf PCL,f
5
Label:
6
goto ReadBit_01
7
goto ReadBit_02
8
goto ReadBit_03
9
goto ReadBit_04
10
goto ReadBit_05
11
12
ChkTab Label
Das Makro ChkTab (Nach Deiner Tabelle) prüft ob Deine Tabelle
vollständig innerhalb der Page gespeichert wurde.
Hallo Anja,
Habe den Code von dir eingebaut. Jetzt wird auch "PCLATH" richtig
gesetzt.
nur beim gegencheck bekomme ich eine Fehlermeldung.
if (high($-1) != high(TableStart))
Error[151] E:\PIC_12_SOURCECODE\INTERRUPT.ASM 88 : Operand contains
unresolvable labels or is too complex
Gruß Siegfried
Siegfried Saueressig schrieb:> nur beim gegencheck bekomme ich eine Fehlermeldung
Du hast aber schon die Makro-Definitionen vor dem Makro-Aufruf im
Quelltext definiert oder?
Gruß Anja
Hallo Anja,
hoffe das ich es so richtig gemacht habe.
1
P_SELW macro Label
2
movlw high Label
3
movwf PCLATH
4
endm
5
6
ChkTab MACRO TableStart
7
if (high($-1) != high(TableStart))
8
error "TABLE CROSSES PAGE"
9
endif
10
ENDM
11
12
STARTUP CODE
13
14
P_SELW Label
15
16
movf STATE,w
17
addwf PCL,f
18
Label:
19
goto ReadBit_01
20
goto ReadBit_02
21
goto ReadBit_03
22
goto ReadBit_04
23
goto ReadBit_05
24
25
ChkTab Label
Habe allerdings, soweit ich das englisch verstanden habe, das es etwas
mit "C" zu tun haben soll.
Hier wurde diese Zeile geschrieben.
if (high (0xFF00+X) != high (0xFF00+Y))
weis allerdings noch nicht, ob es richtig ist.
vielen Dank im voraus.
Gruß Siegfried
PS:
Etwas will mir nicht in den Kopf. MPLAP und Assembler gibt es nicht seit
gestern.
Laut Disassembly bin ich doch in Adressen Bereich 4XX. Warum
aktualisiert sich das Register PCLATH nicht automatisch ?
Denke ich falsch oder hat man keine Lust diesen Fehler in der Software
zu bereinigen.
Trotz Hochsprachen werden immer noch viel in Assembler programmiert um
den Code klein zu halten.
>Etwas will mir nicht in den Kopf. MPLAP und Assembler gibt es nicht seit>gestern.>Laut Disassembly bin ich doch in Adressen Bereich 4XX. Warum>aktualisiert sich das Register PCLATH nicht automatisch ?
Weil bei Assembler nichts automatisch geht.
>Trotz Hochsprachen werden immer noch viel in Assembler programmiert um>den Code klein zu halten.
Auf den Unsinn fallen viele rein.
Ein gut optimierender C-Compiler ist besser als ein schlechter
Assembler Programmierer.
Siegfried Saueressig schrieb:> Trotz Hochsprachen werden immer noch viel in Assembler programmiert um> den Code klein zu halten.
Was völlig sinnlos ist, die MCs haben heutzutage reichlich Flash.
Z.B. Atmels 8-Pinner (ATtiny85) haben schon 8kB, da kann man sich auch
mit float-Zahlen austoben.
Peter
Siegfried Saueressig schrieb:> hoffe das ich es so richtig gemacht habe.
Wenn keine Fehlermeldung mehr auftritt dann ja.
Bei mir funktioniert es jedenfalls sowohl mit PIC16C84 als auch
PIC16F876.
Gruß Anja
Hallo Anja,
> Microchip PIC12F683
leider immer noch nicht.
Habe die Macros an verschiedene Stellen verschoben, auch kein Erfolg.
> Error[151] E:\PIC_12_SOURCECODE\INTERRUPT.ASM 88 : Operand contains> unresolvable labels or is too complex
Diese Zeile wird beanstandet.
> if (high($-1) != high(TableStart))
soweit ich heraus gefunden habe, kommt der Compiler mit mit dem Zeichen
" $ " nicht klar.
auch einen kleinen Testcode vom Bekanntem ohne Erfolg.
> if ($ > 0x1fff)> ERROR "string table out auf page 3"> endif
ist unter umstände eine Einstellung in meinem MPLAP nicht in Ordnung ?
Gruß Siegfried
Siegfried Saueressig schrieb:> soweit ich heraus gefunden habe, kommt der Compiler mit mit dem Zeichen> " $ " nicht klar.
Wieso Compiler ich dachte du arbeitest mit Assembler (MPASM).
Im Assembler ist $ der aktuelle Wert des Programmzählers.
Du könntest natürlich auch ein 2. Label am Ende der Tabelle (vor dem 2.
Makro) einfügen und dieses Label dann anstelle "$" als aktuellen
Programmzähler verwenden.
Arbeitest du mit absolutem oder relativem Code?
ich verwende absolute Adressierung bei meinen Projekten.
Gruß Anja
Hallo Anja,
danke für das Makro, ich habe mir da auch immer einen abgebrochen.
Ich habe schon einiges von dir gelesen, echt super Sachen die du
da drauf hast.
@Holger
ein C oder sonst was Compiler will auch gut bedient werden, da ist
ASM schon einfacher zu Lernen (meine Meinung).
Aber man muss natürlich auch seine Lösungen Umsetzen können und da
wird's dann erst schwierig. Dieses Problem haben so manche aber ebenso
in einer Hochsprache. Für 16Fxxx ist das jedoch mit Kanonen auf Spatzen
geschossen.
Roland
Hallo Anja,
> Wieso Compiler ich dachte du arbeitest mit Assembler (MPASM).
Hast recht.
> Im Assembler ist $ der aktuelle Wert des Programmzählers.
ist mir klar.
> Du könntest natürlich auch ein 2. Label am Ende der Tabelle (vor dem 2.> Makro) einfügen und dieses Label dann anstelle "$" als aktuellen> Programmzähler verwenden.
gleicher Fehler.
> Arbeitest du mit absolutem oder relativem Code?> ich verwende absolute Adressierung bei meinen Projekten.
Habe in Build Optionen -> Mplap/C16/C17/C18 Suite nachgeschaut.
Dort gibt es folgende Möglichkeiten.
1. Ask me
2. Generate absolute code
3. Generate relocatable code
Ask me war aktiviert.
Habe alle Möglichkeiten getestet, ohne Erfolg.
Gruß Siegfried
Welchen PIC hast Du denn jetzt?
Bedenke das die, je nach Typ, intern mit 10, 12, 14 oder 16 (...)
Bit opcodes arbeiten.
Nur weil PIC16 draufsteht, heißt das noch lange nicht, daß
der auch mit 14 Bit arbeitet.
Und selbst mit 14 bit ist die page-size nur 2k...
Vor dem Aufruf von GOTO kann es selbstverständlich ebenso
erforderlich sein PCLATH setzen zu müssen!
(Oder: halte einfach alle Routinen innerhalb des Erreichbaren).
Schau einfach im Datenblatt Deines PICs im instruction set
nach. Dort steht die Bitbreite für GOTO.
Rechne nach, ob es für Dich paßt...
Hallo Anja,
wenn ich von eine Page in eine andere springe,
dann bei " GOTO und CALL " auch den " PCLATH " anpassen,
auch wenn ich in der gleichen *.asm bin ?
Gruß Siegfried
Das hat doch mit der *.asm nichts zu tun. Die Pages beziehen sich auf
die Anzahl der Instruktionen die die du in deinem Programm geschrieben
hast. Hast du schon mehr wie 2048 Instruktionen geschrieben (und bei org
0 angefangen), dann werden die weiteren Instruktionen in die Page 1
geschrieben auch wenn alles in der selben *.asm Datei steht. Du siehst
das ganz gut im Disassembly.
Page0 geht von 0x0000 - 0x07FF
Page1 geht von 0x0800 - 0x0FFF
Page2 geht von 0x1000 - 0x17FF
Page3 geht von 0x1800 - 0x1FFF
Ich habe mir angewöhnt die einzelnen Pages in separate *.asm Dateien zu
schreiben. Am Anfang kommt dann ein org mit der entsprechenden
Startadresse. Sofern eine asm-Datei dann einen Bereich überschreitet
(also z.Bsp. die Page0.asm überschreitet die 0x07FF Grenze) dann
generiert der Assembler eine Fehlermeldung (da in der Page1.asm am
Anfang ja ein org 0x0800 steht).
In Assembler musst du aber den Überblick behalten, wenn du mit goto oder
call (oder PC Manipulationen) in eine andere Page springst und vor einen
solchen Sprung das PCLATH entsprechenden setzen (Das kannst du übrigens
auch mit dem Befehl 'pagesel Label' machen). Nach einem Return solltest
du dann den PCLATH natürlich wieder auf die Rückker-Page setzen oder
halt vor jedem Sprung wieder neu setzen, auch wenn das Ziel in der
selben Page liegt.
Das ganze ist ungefähr so wie das Banking und führt im allgemeinen immer
irgendwann mal zum Absturz und stundenlangen suchen des Fehlers. Bei den
PIC18F gibt es zumindes dieses Paging nicht mehr. Von daher sind die 18F
den 16F vorzuziehen.
Sven