Forum: Mikrocontroller und Digitale Elektronik PIC ASM: obere Adressbytes in Code verwenden


von Sascha (Gast)


Lesenswert?

Die Überschrift ist etwas unverständlich, aber mir ist nichts besseres 
einfallen. Daher erkläre ich mal mein Problem. Ich verwende den 
Microchip MPASM-Assembler und programmiere einen PIC18F24K20.

Sprungmarken werden vom Assembler beim assemblieren ja in Zahlenwerte 
(21bit  breit) für call, goto, bra etc. umgesetzt. Es ist für jede Marke 
bekannt welche Adresse im Flash sie bezeichnet. Wenn man
1
movlw Sprungmarke
sagt, wird daraus zb.
1
movlw 0x56
im Maschinencode, wobei 0x56 das unterste Byte der 21bit-Adresse 
"Sprungmarke" ist. Wie kann ich dem Assembler beibringen, dass er das 
mittlere bzw. oberste Byte der 21bit-Flashadresse nehmen soll? Ich habe 
die low, high und upper-Operatoren in der Hilfe gefunden, aber diese 
funktionieren wohl nur in Relocatable Code.

von Dieter W. (dds5)


Lesenswert?

Versuche mal movlw Sprungmarke >> 8  bzw. movlw Sprungmarke >> 16

von chris (Gast)


Lesenswert?

?? movlw <Sprungaddress> , wirklich, das sollte man vermeiden für den
oberen Bereich, ein bit im höheren Bereich ist ok, mehr sollte aber 
nicht sein. Ansonsten lgoto oder lcall ist dein Freund, wobei dies 
pseudo Befehle
sind, man kann diese nicht mit skip überspringen.

von Sascha (Gast)


Lesenswert?

Hab ich auch schon probiert, dann kommt
1
Error[151] BORDCOMPUTER.ASM 191 : Operand contains unresolvable labels or is too complex

von chris (Gast)


Lesenswert?

dann zeige mal die Zeile und eventuell den Label.

von Sascha (Gast)


Lesenswert?

Ich will movlw Sprungadresse benutzen um mit den Tablepointer-SFRs eine 
Datentabelle zu adressieren, die evtl. länger wird als 256 Bytes. Wären 
es weniger, könnte ich die oberen Adressbytes festlegen.

von Teo D. (teoderix)


Lesenswert?

Sascha schrieb:
> Sprungmarken werden vom Assembler beim assemblieren ja in Zahlenwerte
> (21bit  breit) für call, goto, bra etc.

Nur um Verwirrung zu vermeiden. Es sind natürlich 12Bit. ;)

Lies mal Dabla ab Seite 79.
An die oberen Bits kommt man über ein SFR u. FSR.

Allerdings ist mir schleierhaft, was du wirklich bezwecken willst.

von Chris B. (dekatz)


Lesenswert?

Lade dir mal die MICROCHIP App.Note AN556 runter.
Ist zwar für PIC16 geschrieben, aber die prinzipielle Vorgangsweise bei 
Tableaccess über Seitengrenzen hinweg ist dort gut beschrieben und lässt 
sich sicher für PIC18 anpassen.

von Sascha (Gast)


Lesenswert?

Nein, der Flash hat 21bits Adressbreite (2Mbyte maximal), der RAM hat 
12bit Adressbreite (4kbyte maximal)

Ich will als db-Tabellen im Flash abgelegte Strings konstanter Länge auf 
ein LCD schreiben. Damit das vom Hauptprogramm aus möglichst einfach 
ist, wollte ich mit 2x movlw Sprungadresse TBLPTRL und TBLPTRH mit der 
Startadresse des gewollten Strings laden und dann ein Unterprogramm den 
Rest machen lassen. Falls das mit dem Low- und Highbyte nicht 
funktioniert, werd ich wohl die Strings "durchnummerieren" müssen und 
anhand dieser Nummer die Startadresse berechnen müssen.

von chris (Gast)


Lesenswert?

Ok, dies geht nur bis 64K, darüber geht es nicht mehr, bzw kann auch der
Chip nur 2 bits implementieren, dies wären dann 13bit oder 8K.
Genaueres steht im datenblatt.
Hier ein Beispiel
 movlf high(addresse),PCLATH
 addlw low(addresse) ; hier nur ein Beispiel bei unaligned Table.
 skpnc
 incf PCLATH
 movlw PCL

von chris (Gast)


Lesenswert?

letzter Befehl sollte movwf sein.

von Dieter W. (dds5)


Lesenswert?

Und wie sieht es aus bei
movlw high (Sprungmarke)
und
movlw upper (Sprungmarke)

von Peter D. (peda)


Lesenswert?

Sascha schrieb:
> Nein, der Flash hat 21bits Adressbreite

Laut Datenblatt hat der PIC18F24K20 16kB Flash, also 14Bit-Adressen.

von Sascha (Gast)


Lesenswert?

Trotzdem ist der PC 21bit breit ;-)

Chris: Dein Codeschnipsel setzt imho voraus, dass ich für jeden String 
dessen obere/untere Startadresse manuell eintippe, damit er PCLATH/PCL 
berechnen kann. Damit könnte ich doch auch direkt PCLATH/PCL 
beschreiben. Ich wollte nur das Label eintippen und der Assembler 
ermittelt selber Highbyte/Lowbyte der Startadresse. Das Auslesen des 
Flashs ist bei den PIC18 wesentlich komfortabler als bei den PIC16. 
Wraparound an 256Byte-Grenzen gibts mit TBLPTR nicht.

von Peter D. (peda)


Lesenswert?

Ich verstehe immer noch nicht, was das Problem ist.
Es gibt mehrere Möglichkeiten für Strings im Flash.
1.
Du plazierst einfach vor jeden String ein Label und wählst sie per Label 
aus.

2.
Du plazierst ein Label (Startadresse) vor eine Liste von Strings mit 
konstanter Länge und wählst sie per Startadresse + Index * Länge aus.

3.
Du plazierst vor jeden String ein Label und an anderer Stelle eine 
Tabelle der Labels. Das Auswahl erfolgt dann mit Table_Start + Index * 
Labelsize.
Labelsize dürfte 2 Byte (14 Bit Adresse) sein.

4.
Eine sehr elegante Methode habe ich zu meinen Assemmblerzeiten beim 
8051/AVR benutzt.
Der String steht einfach direkt im Code hinter dem Aufruf der 
Ausgaberoutine und vor dem nächsten Befehl.
Die Ausgaberoutine holt sich die Stringadresse vom Stack, gibt bis zum 
0-Byte aus und springt dann hinter das 0-Byte zurück.
Das geht natürlich nur bei Architekturen, die die Befehle PUSH/POP 
kennen (PIC18 und höher).

: Bearbeitet durch User
von picfan (Gast)


Lesenswert?

Sascha schrieb:
> Sprungmarken werden vom Assembler beim assemblieren ja in Zahlenwerte
> (21bit  breit) für call, goto, bra etc. umgesetzt. Es ist für jede Marke
> bekannt welche Adresse im Flash sie bezeichnet.

Der Programmcounter kann über drei Register manipuliert werden: PCL, 
PCLATH and PCLATU.

PCLATU wird beim dem PIC18F24K20 nicht gebraucht, da nur 16KB Flash.

Peda schlägt mit den Labels eine gute und einfache Lösung für die 
Adressierung von Strings
Gruss Picfan

von Mc Mix (Gast)


Lesenswert?

Hast du es mal mit
     movlw   HIGH sprungmarke
     movlw   LOW  sprungmarke
     movlw   UPPER sprungmarke
versucht.

Zumindest funktionieren beim PIC16 HIGH und LOW.

von Teo D. (teoderix)


Lesenswert?

Mc Mix schrieb:
> Hast du es mal mit
>      movlw   HIGH sprungmarke
>      movlw   LOW  sprungmarke
>      movlw   UPPER sprungmarke
> versucht.

PIC18F
Beitrag "Re: PIC führt Befehl nicht aus"

von chris (Gast)


Lesenswert?

Sascha schrieb:
> Nein, der Flash hat 21bits Adressbreite (2Mbyte maximal), der RAM
> hat
> 12bit Adressbreite (4kbyte maximal)
Stimmt nicht, ist aber egal

>
> Ich will als db-Tabellen im Flash abgelegte Strings konstanter Länge auf
> ein LCD schreiben. Damit das vom Hauptprogramm aus möglichst einfach
> ist, wollte ich mit 2x movlw Sprungadresse TBLPTRL und TBLPTRH mit der
> Startadresse des gewollten Strings laden und dann ein Unterprogramm den
> Rest machen lassen. Falls das mit dem Low- und Highbyte nicht
> funktioniert, werd ich wohl die Strings "durchnummerieren" müssen und
> anhand dieser Nummer die Startadresse berechnen müssen.
Wenn man TBLPTRX benutzt, wieso dann computed gotos verwenden ?


Sascha schrieb:
> Trotzdem ist der PC 21bit breit ;-)
>
> Chris: Dein Codeschnipsel setzt imho voraus, dass ich für jeden String
> dessen obere/untere Startadresse manuell eintippe, damit er PCLATH/PCL
> berechnen kann.
klar
> Damit könnte ich doch auch direkt PCLATH/PCL
> beschreiben.
Stimmt aber nur für den Stringanfang.
> Ich wollte nur das Label eintippen und der Assembler
> ermittelt selber Highbyte/Lowbyte der Startadresse.
angenommen man hat eine puts funktion welche strings ausgibt, und eine
putch funktion, welche Zeichen ausgibt,  dann übergibt man der puts 
Funktion das Label des Strings, dieser addiert aber einen Index für 
einzelne Zeichen dazu, und da muss man dann PCLATH abhängig vom Index 
incrementieren, genau dies macht der gepostete Beispielcode.

> Das Auslesen des
> Flashs ist bei den PIC18 wesentlich komfortabler als bei den PIC16.
> Wraparound an 256Byte-Grenzen gibts mit TBLPTR nicht.
Wie gesagt, wenn man TBLPTR verwendet, wieso dannn computed goto ?

Wenn du z.B. fixe 16Zeichen String machst, dann ist es einfacher ein
.org $ + ($&0xf)
zu verwenden, denn dann sind die Strings aligned.

Ein Beispiel eines codes mit TBLPTR
;******************************************************************
;
;  PutStr - print in-line string via Stack and TBLPTR
;
;  string must be terminated with a 0 byte and does not need
;  to be word aligned
;
PutStr
        movff   TOSL,TBLPTRL    ; copy return address into TBLPTR
        movff   TOSH,TBLPTRH    ;
        clrf    TBLPTRU         ; assume PIC with < 64-KB
PutNext
        tblrd   *+              ; get in-line string character
        movf    TABLAT,W        ; last character (00)?
        bz      PutExit         ; yes, exit, else
        rcall   Put232          ; print character
        bra     PutNext         ; and do another
PutExit
        btfsc   TBLPTRL,0       ; odd address?
        tblrd   *+              ; yes, make it even (fix PC)
        movf    TBLPTRH,W       ; setup new return address
        movwf   TOSH            ;
        movf    TBLPTRL,W       ;
        movwf   TOSL            ;
        return                  ; return to address after string
;


nochmals, wozu computed goto wenn du TBLPTR verwenden willst ?

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.