www.mikrocontroller.net

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


Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, auf ein neues

Habe Problem Sprungtabelle in Externer ASM Datei
movf STATE,w
addwf PCL,f
goto ReadBit_01
goto ReadBit_02
goto ReadBit_03
goto ReadBit_04
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

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du musst PCLATH mit dem richtigen Wert laden.
In deinem Fall müsste das 0x04 sein.
movlw 0x04
movwf PCLATH
movf STATE,w
addwf PCL,f
goto ReadBit_01
goto ReadBit_02
goto ReadBit_03
goto ReadBit_04
goto ReadBit_05

Dann sollte er auch an die Richtige Stelle springen.

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Torsten Schwalm (torstensc)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Anja (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:

P_SELW  macro  Label
  movlw  high  Label
  movwf  PCLATH
  endm

 P_SELW Label

 movf STATE,w
 addwf PCL,f
Label:
 goto ReadBit_01
 goto ReadBit_02
 goto ReadBit_03
 goto ReadBit_04
 goto ReadBit_05

 ChkTab Label

Das Makro ChkTab (Nach Deiner Tabelle) prüft ob Deine Tabelle 
vollständig innerhalb der Page gespeichert wurde.

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

Gruß Anja

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Anja (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Anja,

hoffe das ich es so richtig gemacht habe.

P_SELW  macro  Label
  movlw  high  Label
  movwf  PCLATH
  endm

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

STARTUP  CODE   

P_SELW Label

 movf STATE,w
 addwf PCL,f
Label:
 goto ReadBit_01
 goto ReadBit_02
 goto ReadBit_03
 goto ReadBit_04
 goto ReadBit_05

 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.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Siegfried Saueressig (dieleena)
Datum:

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

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Leider kann ich dir bei beiden Antworten nicht zustimmen.

Mir doch doch egal;)

Autor: Anja (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Anja (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Roland Fischer (r_fischer)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kannst es auch mal so probieren, dann kannst du dir die Makros 
sparen.
    movlw   high TABLESTART 
    movwf   PCLATH 
    movlw   low TABLESTART
    addwf   STATE, w 
    btfsc   STATUS, C
    incf    PCLATH, f 
    movwf   PCL
TABLESTART 
   goto   ReadBit_01
   goto   ReadBit_02
   goto   ReadBit_03
   goto   ReadBit_04
   goto   ReadBit_05

Gruß Flo

Autor: AkkiSan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: stepp64 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: stepp64 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab gerade noch mal in eines meiner Programme geschaut. Ich denke du 
willst genau das machen, was ich so gelößt habe:
Sprungverteiler
  movwf  tmp1      ;W sichern
  movlw  High (JumpMenü)    ;High Tabellen Vektor holen
  movwf  PCLATH      ;Vektor nach PCLATH schreiben
  movlw  Low (JumpMenü)    ;Low Tabellen Vektor holen
  addwf  tmp1,w      ;Low Vektor hinzu addieren
  btfsc  STATUS,C    ;Gab es einen Übertrag?
  incf  PCLATH,f    ;ja, PCLATH incrementieren
  movwf  PCL      ;und springen

JumpMenü  
  goto  Menü00      ;Logdaten anzeigen
  goto  Menü01      ;PIN Tastatur ändern
  goto  Menü02      ;PIN Funk ändern
  goto  Menü03      ;PIN Konfig ändern
  goto  Menü04      ;Alarmlinien Delay Zeit
  goto  Menü05      ;Alarmlinien Delay welche Linie

Hoffe es hilft dir.

Gruß
Sven

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.