Forum: Mikrocontroller und Digitale Elektronik [PIC] Assembler Problem Sprungtabelle in Externer ASM Datei


von Siegfried S. (dieleena)


Lesenswert?

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

von Flo (Gast)


Lesenswert?

Du musst PCLATH mit dem richtigen Wert laden.
In deinem Fall müsste das 0x04 sein.
1
movlw 0x04
2
movwf PCLATH
3
movf STATE,w
4
addwf PCL,f
5
goto ReadBit_01
6
goto ReadBit_02
7
goto ReadBit_03
8
goto ReadBit_04
9
goto ReadBit_05

Dann sollte er auch an die Richtige Stelle springen.

von Siegfried S. (dieleena)


Lesenswert?

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

von Flo (Gast)


Lesenswert?

Dann musst du am Anfang deiner Tabelle
org 0x400
oder org 0x500
schreiben.

Dann beginnt die Tabelle genau an der Stelle, die hinter dem org steht.

von Torsten S. (torstensc)


Lesenswert?

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

von Anja (Gast)


Lesenswert?

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.

1
ChkTab  MACRO   TableStart
2
    if (high($-1) != high(TableStart))
3
    error "TABLE CROSSES PAGE"
4
    endif
5
        ENDM

Gruß Anja

von Siegfried S. (dieleena)


Lesenswert?

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

von Anja (Gast)


Lesenswert?

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

von Siegfried S. (dieleena)


Lesenswert?

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.

von holger (Gast)


Lesenswert?

>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.

von Peter D. (peda)


Lesenswert?

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

von Siegfried S. (dieleena)


Lesenswert?

Hallo Holger,
Leider kann ich dir bei beiden Antworten nicht zustimmen.
Gruß Siegfried

von holger (Gast)


Lesenswert?

>Leider kann ich dir bei beiden Antworten nicht zustimmen.

Mir doch doch egal;)

von Anja (Gast)


Lesenswert?

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

von Siegfried S. (dieleena)


Lesenswert?

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

von Anja (Gast)


Lesenswert?

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

von Roland (r_fischer)


Lesenswert?

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

von Siegfried S. (dieleena)


Lesenswert?

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

von Flo (Gast)


Lesenswert?

Du kannst es auch mal so probieren, dann kannst du dir die Makros 
sparen.
1
    movlw   high TABLESTART 
2
    movwf   PCLATH 
3
    movlw   low TABLESTART
4
    addwf   STATE, w 
5
    btfsc   STATUS, C
6
    incf    PCLATH, f 
7
    movwf   PCL
8
TABLESTART 
9
   goto   ReadBit_01
10
   goto   ReadBit_02
11
   goto   ReadBit_03
12
   goto   ReadBit_04
13
   goto   ReadBit_05

Gruß Flo

von AkkiSan (Gast)


Lesenswert?

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...

von Siegfried S. (dieleena)


Lesenswert?

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

von stepp64 (Gast)


Lesenswert?

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

von stepp64 (Gast)


Lesenswert?

Hab gerade noch mal in eines meiner Programme geschaut. Ich denke du 
willst genau das machen, was ich so gelößt habe:
1
Sprungverteiler
2
  movwf  tmp1      ;W sichern
3
  movlw  High (JumpMenü)    ;High Tabellen Vektor holen
4
  movwf  PCLATH      ;Vektor nach PCLATH schreiben
5
  movlw  Low (JumpMenü)    ;Low Tabellen Vektor holen
6
  addwf  tmp1,w      ;Low Vektor hinzu addieren
7
  btfsc  STATUS,C    ;Gab es einen Übertrag?
8
  incf  PCLATH,f    ;ja, PCLATH incrementieren
9
  movwf  PCL      ;und springen
10
11
JumpMenü  
12
  goto  Menü00      ;Logdaten anzeigen
13
  goto  Menü01      ;PIN Tastatur ändern
14
  goto  Menü02      ;PIN Funk ändern
15
  goto  Menü03      ;PIN Konfig ändern
16
  goto  Menü04      ;Alarmlinien Delay Zeit
17
  goto  Menü05      ;Alarmlinien Delay welche Linie

Hoffe es hilft dir.

Gruß
Sven

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.