Computed GOTO failing

Thread Starter

corsair

Joined Mar 6, 2010
51
I was trying to do a simple computed goto, where it was something like:

Rich (BB code):
       movlw 0x3
       call     hex_to_7seg
...
hex_to_7seg:
       addwf PCL
       retlw xx
       retlw xx
       retlw xx
       retlw xx
       etc..
But when it adds 0x3 to the PCL, it goes bogus. Anyone know what the problem may be? I have screenshots attached which show a trace.

Update:
I found this somewhere, but it still doesn't seem to work. Instead of adding 0x3 it will add 0x6. The whole adding thing, even if I try to add 0x0, will make it flip out.
3) Look for instruction that modifies PCL like ADDWF PCL, W. Since 18 series address are WORD aligned, you need to add 2 lines before that instruction. CLRF STATUS, C and RLCF WREG, F.
 

Attachments

Last edited:

MMcLaren

Joined Feb 14, 2010
861
The program counter increments by two bytes for 18F' 16-bit instructions and so you need to multiply your "index" by two before modifying PCL.

Regards, Mike

Rich (BB code):
segtbl
        rlncf   WREG,W          ; index 0..9 -> 0,2,4...E    
        addwf   PCL,F           ;                                
        retlw   b'00111111'     ; "0"   -|-|F|E|D|C|B|A        
        retlw   b'00000110'     ; "1"   -|-|-|-|-|C|B|-         
        retlw   b'01011011'     ; "2"   -|G|-|E|D|-|B|A         
        retlw   b'01001111'     ; "3"   -|G|-|-|D|C|B|A      
        retlw   b'01100110'     ; "4"   -|G|F|-|-|C|B|-       
        retlw   b'01101101'     ; "5"   -|G|F|-|D|C|-|A        
        retlw   b'01111101'     ; "6"   -|G|F|E|D|C|-|A         
        retlw   b'00000111'     ; "7"   -|-|-|-|-|C|B|A          
        retlw   b'01111111'     ; "8"   -|G|F|E|D|C|B|A         
        retlw   b'01101111'     ; "9"   -|G|F|-|D|C|B|A
 

Thread Starter

corsair

Joined Mar 6, 2010
51
Hmm, yea I read that somewhere but it still doesn't seem to work. It doesn't like it when I add anything (even 0x0) to PCL. It compiles correctly and everything, it just doesn't goto the correct location. In this case it, instead of going from 0x26 to 0x29, it goes from 0x26 to 0xFE. But yes, that was another thing I was doing incorrectly. So it should be going from 0x28 (since I add that one instruction) to 0x2D.
 

BMorse

Joined Sep 26, 2009
2,675
I had run into a similar problem with a PIC16F628A, one way I found to fix it was this:

I added 5 more lines of data in the data table.....
Rich (BB code):
bin2seg    addwf    PCL, F            ; Jump into the lookup table
        retlw   0x7E    ;b'01111110'        ;0
        retlw   0x0C    ;b'00001100'        ;1
        retlw   0xB6    ;b'10110110'        ;2
        retlw   0x9E    ;b'10011110'        ;3
        retlw   0xCC    ;b'11001100'        ;4
        retlw   0xDA    ;b'11011010'        ;5
        retlw   0xFA    ;b'11111010'        ;6
        retlw   0x0E    ;b'00001110'        ;7
        retlw   0xFE    ;b'11111110'        ;8
        retlw    0xCE   ;b'11001110'        ;9
        retlw    0xFF   ;b'00000000'        ;Blank
        retlw    0xFF   ;b'00000000'        ;Blank
        retlw    0xFF   ;b'00000000'        ;Blank
        retlw    0xFF   ;b'00000000'        ;Blank
        retlw    0xFF   ;b'00000000'        ;Blank
Then before calling the lookup table, I made sure the digit I was passing to PCL was within my table boundaries....
Rich (BB code):
    movfw  cnt_dig4  ;load number to display
    andlw   0x0F       ;make sure it is within table limits
    call      bin2seg    ;Convert number in W to the segment value
    movwf  PORTB     ;Send value returned in W to the segments
I am not sure if this is whats causing your issue but I just thought it was worth a mention...


B. Morse
 

rjenkins

Joined Nov 6, 2005
1,013
You need to set the high half of the program counter to the table location, and make sure the table does not cross a memory page.

I always start tables at a new program origin, well above the main program, rather than check each lookup for page wrapping, it's simpler and quicker.


Have a look at this article:
http://www.piclist.com/tecHREF/microchip/tables.htm

The section by Mike Keitz about a page down (using W as the index) looks like what you need.
 

eblc1388

Joined Nov 28, 2008
1,542
Not only must one ensure the value added to the PCL would stay within the table boundary, one must ensure that the whole table is NOT crossing a page boundary in the flash memory address.

Note to OP, look at the flash address of the table to see if it is situated in the boundary of two memory pages, if so, move it around until it doesn't. One can place additional codes for table read operation such that table crossing page boundary will no longer be an issue, like the following:

Rich (BB code):
        movlw LOW Table         ;get low 8 bits of Table address
        addwf offset,F          ;add offset to Table and save for later use
                                ;if page is crossed, carry will be set
        movlw HIGH Table        ;next get high 5 bits of Table address
        btfsc STATUS,C          ;check page crossed? Skip next if NO
        addlw 1                 ;yes, increment W
        movwf PCLATH            ;place into PCLATH
        movf offset,w           ;load computed offset into W
        call Table              ;call to table
;
;
;
Table:
        movwf PCL,F        ;load computed offset to PCL
        retlw  A              ;return the ASCII char A
        retlw  B              ;return the ASCII char B
        retlw  C             ;return the ASCII char C
 

Thread Starter

corsair

Joined Mar 6, 2010
51
omg this is a lot more complicated than i thought, haha. ill try to do some more reading and ill let u know if i get it fixed... thanks guys

btw, i have a PIC18F4550 processor. a lot of these hints are saying things like:

This application note shows how to implement a table
look-up for the following devices:
• PIC12CXXX
• PIC12CEXXX
• PIC16CXXX
• PIC16CEXXX
• PIC16FXXX
The examples shown are for the PIC16CXXX family.
An explanation of differences for the PIC16C5X family
is at the end of this application note.
im still going to read them, nonetheless. just not sure if they will apply
 

Thread Starter

corsair

Joined Mar 6, 2010
51
ah yes! got it working, i used the code eblc posted and it worked after modifying it a little for the pic18f =) tyvm!! (time to take some tylenol)
 
Top