Forum: Mikrocontroller und Digitale Elektronik rcall/ relativ call Anweisung PIC18F85J10


von Olli Holly (Gast)


Lesenswert?

Hi,

ich stelle gerade von PIC16F auf 18F um und habe ein wenig mit einigen 
der neuen Befehle zu kämpfen.
Einer der Befehle ist der rcall Befehl. Das was im Datenblatt zur 
"INtruction" steht ist mir recht klar, ich kann damit den PC 
vor/zurückschieben. Wenn ich ein kleines Beispielprog mal in MPASM 
schreibe (relocatable code):

  movlw  b'11111100'      ;2er Complement = +4
  movwf  Example,ACCESS
  rcall  Example
  goto  Tut1
  goto  Main
  goto  Tut2
  goto  Main
  goto  Tut3

Main:
  goto   Main


sollte rcall nach meiner Vorstellung den ProgrammCounter um 4 Stellen
weiter schieben. Da es sich beim PIC18F um 16bit Anweisungen handelt 
sollten dies wie ich denke 2 Zeilen im Programm sein, allerdings rcall 
weder zu Main noch zu einem der TutX Unterprogs.
Was mache ich falsch ?
Grundlegend scheint das PCL Register sich zu ändern:
in der Zeile vor dem rcall Befehl steht der Counter in MPSIM auf
b'10111110' (0xbe), ein ein augeblick später aber bei b'01111100' 
(0x7c), irgedwas durchschau ich da nicht bitte helft mit mal auf die 
Sprünge (<- das könnt Ihr Wörtlich nehmen) ???

von (prx) A. K. (prx)


Lesenswert?

Olli Holly schrieb:

>   movwf  Example,ACCESS
>   rcall  Example

Das ergibt wenig Sinn. Entweder ist "Example" ein Objekt im RAM, dann 
ist der MOVWF sinnvoll und der Aufruf RCALL unsinnig, oder "Example" ist 
ein mit RCALL oder CALL aufrufbares Unterprogramm im ROM und der MOVWF 
ist unsinnig.

RCALL ist eine Version des Befehls CALL mit eingeschränker Reichweite. 
Das Ziel steht als Distanz im Befehl, nicht in W oder [W]. Die 
Verwendung im Programm ist exakt identisch, die Distanzrechnung erledigt 
der Assembler. Bei den PIC18 ist CALL 2 Worte lang, um ohne Banking den 
ganzen Code erfassen zu können, daher gibt es Bedarf für eine kürzere 
Version für Ziele in näherer Umgebung.

Ich hätte allerdings erwartet, dass der Assembler nicht einfach über die 
Verwendung des Symbols "Example" im falschen Kontext hinwegsieht.

von Olli Holly (Gast)


Lesenswert?

Danke für die zügige Antwort. Dann liegt hab ich tatsächlich eine ganz 
falsche Vorstellung vom rcall Befehl gehabt.
Dann wäre die Frage nun allerdings wie ich mit einem Wert bzw einer 
Variable
an unterschiedliche Punkte im Programm springen kann, denn auch folgende 
Variante bringt mir in einem kleien Testprog keine Glück.

Kann ich den PCL

  movlw  .4
  addwf  PCL,f,ACCESS
  goto  Tut1
  goto  Main
  goto  Tut2
  goto  Main
  goto  Tut3

Main:
  goto   Main

Das Ziel das ich habe ist, auf möglichst flinke Art und Weise ein 
Schrittkette zu realisieren die eben in Abhängikeit von einer Variablen 
zum richtigen Unterprog springt.
Man könnte natürlich mit CPFSEQ die Variable für jedes Unterprog einmal 
abfragen, aber ich bin mir ziehmlich sicher das der ProgCounter eine 
elegantere Lösung bietet, ich komm nur irgendwie nicht auf den Trichter!

Wie Springe ich mit PCL durch den ProgSpeicher ? Muss ich noch irgendein 
Bereich declarieren oder sowas ??

Übrigens: MPASM schmeißt tatsächlich ERROR noch ein WARNING raus, könnte 
auch ein Hinweis drauf geben das man damit noch irgedwas sinvolles 
anstellen kann.

von (prx) A. K. (prx)


Lesenswert?

Datenabhängige Sprünge finden wie bei 8-Bit PICs allgemein üblich durch 
Manipulation von PCL statt, in Verbindung mit PCLATx. In der Reference 
steht einiges darüber drin (computed goto).

Zu den hässlichen Seiten gehört freilich, dass man dabei aufgrund der 
8-Bit Rechnung allzu abhängig von der Lage des Codes innerhalb von 
256-Byte Pages wird. Bei relocatable code ist das zu beachten.

von Olli Holly (Gast)


Lesenswert?

Danke A.K. jetzt bin ich im Bilde, falls sich noch jemand schlau lesen 
möchte:

Offset Sprünge
;*********************************************************************** 
***
Wenn ein Sprung in Abhängigkeit von einer Variablen gemacht werden soll
um Tabellenwerte abzufragen oder um eine Schrittkette zu realisieren, 
dann
müssen ein paar Dinge bekannt sein.
- Die Sprünge können mit dem PCL Register ausgeführt werden
- Für die Sprünge müssen alle 3 Bytes gesetzt werden (PCLATU/H/PCL)
- Die Sprünge dürfen nur in einem CodeBereich von 256Byte sein (auch 
PIC18F)
- Die Befehlsbreite der zu überspringenden Befehle muss bekannt sein.

Beispiel:


  movlw  .4
  movwf  Example,ACCESS
  call  Choice

Beispiel  code  0x0400
Choice
  movf  PCL,w          ;PCLATH/U werder durchs lesen in Temp
        ;regs geladen und ergänzen beim schrieben
        ;mit PCL die Adresse auf 21bit
  movf  Example,w
  addwf  PCL,f,ACCESS  ;1word Befehlsbreite
  goto  Tut1    ;2wrd Befehlsbreite, Tut1-->Example=0
  goto  Tut2    ;2wrd Befehlsbreite, Tut2-->Example=4
  goto  Tut3    ;2wrd Befehlsbreite, Tut3-->Example=8

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.