Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC18F and GOTO $-6

Status
Not open for further replies.

yngndrw

New Member
Hi,

I've searched on google and these forums but havn't found a solution so I thought I'd post a thread.

I'm having troubles with getting GOTO $-X working on a PIC18F.

On PIC16F's, it works perfectly, but stepping through it on MPLAB's PIC SIM, it seems to not jump far enough.

Am I missing something with the PIC18F's ?

Thanks.
 
Yes, you're missing the fact that each instruction is 2 bytes wide. Double word instructions are 4 bytes wide.

Code:
;
;
        movlw   h'04'           ;
        bra     $+4             ; same as bra label1
        nop                     ;
label1  nop                     ;
 
This method will get you into trouble with retlw type tables too. Watch out.

Code:
;
;  enter with index (0..3) in WREG
;
Example_Table
        rlncf   WREG,W          ; multiply index by 2
        addwf   PCL,F           ;
        dt      0x44            ;
        dt      0x55            ;
        dt      0x66            ;
        dt      0x77            ;
Unfortunately, the dt/retlw type tables use memory inefficiently. You only get one byte of storage in a 16 bit instruction word. That's why you should explore the TBLPTR table method.

You're gonna have so much fun on the 18F's (grin).

Regards, Mike
 
Thanks for your replies.

I've tried calculating the number of words used then adjusting my GOTO's, however it seems to jump too far. I've also found that by changing the GOTO from $-20 to $-18, it seems to jump 3 commands - 8 bytes worth of commands.

Thanks for the heads up on the tables, I'll look into the TBLPTR method once I get this working.

Here's my code, with the calculated number which jumps way too far:
Code:
LCD_STRING_SLOW	MACRO	STRING

				CLRF	LCD_STRING_POSITION
				MOVF	LCD_STRING_POSITION,	W; 2 - second goto should jump to here

				NOP; 2

				CALL	STRING; 4

				XORLW	0x00; 2
				BTFSC	STATUS,	Z; 2
				GOTO	$+20; 4

				CALL	LCD_DATA; 4

				MOVLW	0xFF; 2
				CALL	DELAY; 4

				INCF	LCD_STRING_POSITION,	F; 2
				GOTO	$-28; 4

				MOVLW	0x00 ; - first goto should jump to here
				ENDM
 
Do you men 20 decimal (0x14) or 0x20 (32 dec)?

If you are choose not to use base identifiers like (0x, H, . ) the assembly will use the default radix which most likely is Hex if not configured for anything else.

To set the radix from withing an .asm file use
RADIX DEC
RADIX HEX
RADIX OCT...
 
Ahh, I didn't realise it was in HEX, I feel stupid now.

I havn't made jumps longer than 9 before so it never occured to me.

Thank you very much. :)
 
You could always use a couple labels (grin)...

Anyway, since you're printing strings, here's a nifty 18F' method I use for printing strings which are stored in-line with my code.

It demonstrates a few things worth noting; (1) pulling a return address from the stack, (2) using TBLPTR to access individual bytes of table data, (3) how it's important to word align program counter addresses {no odd addresses, thank you}, and (4) how to modify the return address on the stack.

Just replace the rcall Put232 instruction with an rcall PutLCD instruction to your "put" code...

Have fun. Mike

Code:
;
;  _Print macro
;
_Print  MACRO   str             ; print in-line string macro
        call    PutString       ;
        db      str,0
        ENDM
;
;  usage examples
;
        _Print  "Satellite AOS:\n\r"
        _Print  "Satellite LOS:\n\r"
;

;******************************************************************
;
;  PutString subroutine - print in-line string via Stack and TBLPTR
;
;  string must be terminated with a 00 byte and does not need
;  to be word aligned
;
PutString
        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                  ;
;
;******************************************************************
 
The reason why I wasn't using labels was because it was for a macro, which complained that the labels were being redefined when the macro was used more than once.

There's a few things I don't understand about your code:
1) What does DB do ? I've searched on google but can't find what it does. Does it store the data in the EEPROM ?
2) What's the difference between RCALL and CALL, same goes for the difference between GOTO and BRA ?
3) Why do you have to store the return address ? Why does it not just stay as it was ?
4) Why is the DB after the CALL in the macro ? If DB is what I think it is, how does that display what hasn't yet been stored ?

I have a lot to learn as far as ASM goes. :(

Thank you for the help. :)

Edit:
I've just looked through the .lst and the DB command makes sense now, as does the reason it's after the CALL and also the reason for storing the return address.

The only thing that I don't understand now is:
2) What's the difference between RCALL and CALL, same goes for the difference between GOTO and BRA ?

Thanks.
 
Last edited:
A 1-word rcall instruction is used for "short" calls where a regular 2-word call instruction can span the entire flash address space. Same thing for the 1-word bra instruction vs. the 2-word goto instruction.

Mike
 
BTW, when you want to use labels in a macro you need to define them as "local"...

Code:
;
;  _Title macro - home cursor, clear screen, print a string
;
_Title  macro   str             ;
        local   String, Print
        movlw   low String      ;
        movwf   PTRL            ;
        movlw   high String     ;
        movwf   PTRH            ;
        goto    Print           ;
String  dt      0x1b,"[2J"      ; home cursor, clear screen
        dt      str,0
Print   call    PutString       ; print string
        endm
 
Would it be nice of the compiler gave suggestions along with its denials.

-Duplicate label found.
-May I suggest using "local x, y" since one of the duplicates were detected inside a macro.


Would be nice but most likely would cost too much anyway, unless someone in the business world actualy gave a rats ... and cared.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top