PIC ASM: obere Adressbytes in Code verwenden

Gast #5787545
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.
Gast #5787574
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.
Gast #5787590
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.
Gast #5787655
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.
Gast #5787665
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
Gast #5787706
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.
#5788336
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).
Gast #5788987
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
Gast #5793070
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 ?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren