PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Tabellen in MPasm & Fehlermeldung bei Page-überschreitun



*Mario*
10.05.2006, 09:05
Hallo,

ich würde eure Hilfe brauchen. Ich habe im Programmspeicher eine "retlw" Tabelle angelegt.


#define TABLELENGTH D'25'

....
movwf offset
call char_table
....

char_table
pageselw char_table
movf offset,w
addwf PLCATH,f
retlw B'01001011'
retlw B'11000011'
retlw B'01011001'
....

Dabei dard der addwf-Befehl aber keinen Überlauf produzieren. Ich möchte nun eine Fehlermeldung beim Assemblieren ausgeben lassen, falls das der Fall ist. Meine bisherige Lösung schluckt der Assembler nicht, meint das Label kann er nicht finden, oder der Ausdruck sei Ihm zu komplex (Da hilft auch nix den Ausdruck aufzutröseln, etc.).

if ((char_table+TABLELENGTH) % 0x100) < low(char_table)
error "Table crosses 256-Byte boundary"
endif

Wie kann ich das machen?

Danke für Eure Hilfe
Mario

kalledom
10.05.2006, 10:03
Warum verwendest Du nicht PCLATH, dann spielt es keine Rolle, wo die Tabelle steht und / oder wie lang die ist ?
http://www.domnick-elektronik.de/picasm.htm#CompGoto

*Mario*
11.05.2006, 08:34
Hallo kalledom,

danke für den Tipp. Der code selber ist (meines erachtens) aber falsch, d.h. leidet auch an dem Überlaufproblem. Hat mich allerdings auf die Lösung geführt!
Hier ist der "relocatable" code:



AnzTage
pageselw TblTage ; PCLATH setzen
decf zMon,W ; Monat - 1 nach W-Register
addwf PCL,w ; PCL + Monat
btfsc STATUS,C
incf PCLATH,f
decf zMon,W ; Monat - 1 nach W-Register
TblTage addwf PCL,f

retlw 31


Korrigiert mich wenn ich falsch liege!

Grüße
Mario

kalledom
11.05.2006, 09:10
Hallo Mario,
Du hast mich zum Nachdenken gebracht :-)
Lese doch mal die AN556 'Implementing a Table Read' von Microchip, bei mir ist jetzt der 'Groschen' gefallen. Mein Beispiel funktioniert nur, wenn die 256 Byte-Grenze nicht innerhalb der Tabelle liegt !
Dein Vorschlag hat einen Haken: es ist unklar, was in PCLATH zum Zeitpunkt des evtl. Increment drin steht ! PCLATH ist ein Latch !

PICture
12.05.2006, 07:36
Hallo!

Ich bin leider kein Programmierer und deswegen mache ich es einfach.

Vor jeder 256 Byte langen "retlw" Tabelle (look-up table) schreibe ich "ORG 0x(HH00-2)" und lade den Wert HH in PCLATH direkt vor dem Sprung in die gewähle Tabelle. Zum Beispiel für HH=7F ist ORG 0x(7F00-2), also ORG 0x7EFE.

MfG

*Mario*
12.05.2006, 08:14
Hallo PICTure, kalledom,

also ich habe mir nun die AN556 angesehen. Example 5 dort drinnen kommt dem schon recht nahe. Der Inhalt des PCLATH registers ist beim Ausführen des Table-Jump schon bekannt, d.h. 'pageselw Tbl' wird in 'movlw high(Tbl) & movwf PCLATH' umgesetzt. Oder hast Du damit was anderes gemeint?
Die Lösung über die ORG-Anweisung ist zwar einfach, entbindet dem Programmierer aber nicht die Hausaufgaben des Assemblers mitzudenken. Ich muss dann immer aufpassen, dass der Code davor noch reinpasst. Wenn ich den ändere, muss ich wieder an der ORG-Anweisung drehen. Das ist mir einfach zu mühsam :(.

Grüße
Mario

kalledom
12.05.2006, 09:59
Hallo Mario,
Dein Beispiel ist richtig.
Die Assembler-Directive 'pagesel' bzw. 'pageselw' war mir unbekannt, und was die eigentlich so macht.
Im MPASM User's Guide habe ich 'pagesel' gefunden, jedoch nichts über 'pageselw'.
Kennst Du den Unterschied ?

PS: In Deinem Beispiel darf die Tabelle maximal 250 Befehle lang sein, sonst ist, wenn die 256-er Grenze nach dem 250-ten Befehl kommt, das Problem wieder da .... :-)

phaidros
12.05.2006, 23:09
pageselw benutzt das W-Register. Es wird dadurch verändert. Das muss im umgebenden Code beachtet werden.
pagesel benutzt statt dessen bit-set Befehle (bsf). W wird nicht verändert.

*Mario*
18.05.2006, 10:22
Hallo Kalledom,

phaidos hat den Unterschied zwischen pagesel und pageselw bereits erklärt, da kann ich nicht mehr zufügen. Sollte in der Hilfe zum Assembler unter den "Direktiven" zu finden sein.

Tabelle kann doch 255 bytes lang sein oder? Für längere Tabellen muss dann halt eine 16-bit Addition vorgeschoben werden. Wenn Bedarf besteht, überleg ich mir dazu eine effiziente Lösung und stells hier rein.

Grüße
Mario

kalledom
18.05.2006, 12:11
Hallo Mario,
ich denke, Du darfst die Addition des Tabellen-Offset mit dem Programm-Counter-Low nur 1 mal durchführen, weil sonst je nach Programm- oder Tabellen-Adresse die erste Addition keinen Übertrag ergibt, die zweite Addition 4 Befehle / Adressen weiter jedoch einen Übertrag ergeben würde, der nicht in PCLATH berücksichtigt wird.
Deshalb darf die Tabelle auch nur 256 Adressen minus 3 Befehle lang sein.

PS: in meinem MPASM User Guide aus dem PICStart-Paket ist nur 'pagesel' beschrieben.

PICture
20.05.2006, 06:51
Hallo *Mario*!

Schon wieder eine einfache Idee, die Dir sicher nicht gefallen wird. Aber trotzdem erkläre ich sie kurz. Wenn man eine look-up table überprufen will, ob sie nicht zu lang ist, dann plaziert man sie auf der letzten Seite (page) des RAMs und assembliert (mit MPASM). Wenn die Tabelle länger als 256 Bytes ist, bringt MPASM eine Meldung: "Adress exceeds maximum range for this processor".

MfG

kalledom
20.05.2006, 10:32
Noch 2 Möglichkeiten für 256 Byte lange Tabellen:

; 1. Möglichkeit

AnzTage
movlw HIGH(TblTage) ; PCLATH setzen
movwf PCLATH
decf zMon,W ; Monat - 1 nach W-Register
addwf PCL,W ; 1 ; PCL + Monat nach W
btfsc STATUS,C ; 2 ; ... kein Übertrag
incf PCLATH ; 3 ; + 1 für 256-er-Grenze

addlw 8 ; 4 ; + 8 Befehle/Adressen
btfsc STATUS,C ; 5 ; ... kein Übertrag
incf PCLATH ; 6 ; + 1 für 256-er-Grenze

decf zMon,W ; 7 ; Monat - 1 nach W-Register
addwf PCL ; 8 ; PCL + Offset

TblTage
retlw 31
.....


; 2. Möglichkeit

AnzTage
movlw HIGH(TblTage) ; PCLATH setzen
movwf PCLATH
decf zMon,W ; Monat - 1 nach W-Register
call GetTage

org 0x??FF
GetTage
movwf PCL
TblTage
retlw 31
.....