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.

PIC: Table lookup across page boundary

Status
Not open for further replies.

eblc1388

Active Member
Hi,

I need to do a lookup table that span page boundaries. Therefore I have to do a 13-bit offset call. I look up Microchip's datasheet and found one but it trashes my offset value in doing the call. So I try to write my own version that does not trash my offset value. It comes up shorter than the Microchip's one.

Common sense tells me that a "better" solution is often the results of overlooking some important issues.

Can you spot any errors/shortcomings in the code I use?


Code:
Example by Microchip, trash value in OFFSET file reg
====================================================
org 0x80
movlw LOW Table    ;get low 8 bits of address
addwf offset,F     ;do an 8-bit add operation
movlw HIGH Table   ;get high 5 bits of address
btfsc status,c     ;page crossed?
addlw 1            ;yes then increment high address
movwf PCLATH       ;load high address in latch
movf offset,w      ;load computed offset in w reg
;
call Table
;
;
Table:
movwf PCL,F        ;load computed offset in PCL
retlw ’A’          ;return the ASCII char A
retlw ’B’          ;return the ASCII char B
retlw ’C’          ;return the ASCII char C


EXAMPLE: My version, shorter, does not destroy OFFSET value
===========================================================
org 0x80
movlw HIGH Table        ;get high 8 bits of Table address
movwf PCLATH            ;save to PCLATH (may not be correct, yet)	
movlw LOW Table         ;get Table low address
addwf offset,W          ;add value of offset, keep result in W
                        ;if page is crossed, carry will be set
btfsc STATUS,C          ;check page crossed? Skip next if NO
incf PCLATH             ;yes, increment PCLATH
;
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

Thanks for your comments.
 
It looks ok to me (except missing ORG statement).
Nigel would say "Microchip example programs are known to be buggy" so in this case it means unoptimal and doesn't preserve offset value...
 
Jay.slovak said:
It looks ok to me (except missing ORG statement).
Nigel would say "Microchip example programs are known to be buggy" so in this case it means unoptimal and doesn't preserve offset value...

Thanks. Most of the time Microchip's code is good(at least to me so far, mind you I have only 30 days' experience in PIC coding). If one happens to spot a "mistake" most likely case is the person does not understand certain hidden aspects of the coding requirement.

The safest way is to ask in an open forum as there are many experienced code writers around.
 
I assume you're using a mid-range kind of PIC like a PIC16F877. To quote the datasheet:

"The upper bits (PC<12:8>) are not readable but are indirectly writable through the PCLATH register."

Your code will fail because the instruction "incf PCLATH" does a read-modify-write but PCLATH is write-only.
 
motion said:
I assume you're using a mid-range kind of PIC like a PIC16F877. To quote the datasheet:

"The upper bits (PC<12:8>) are not readable but are indirectly writable through the PCLATH register."

Your code will fail because the instruction "incf PCLATH" does a read-modify-write but PCLATH is write-only.

I think you have misread the meaning of the data sheet. While the upper bits of the program counter are not readable, PCLATH is readable and can be incremented as the OP suggested. It must be readable in order to save it in interrupt routines.

You did have me worried there for a minute as I have used BSF and BCF on PCLATH to do efficient calls/jumps between banks in the past.

Mike.
 
One other thing, if the above code is already in a subroutine then there is no need for the Call Table instruction. Just movwf PCL,F will work on it's own. The call is only required to place a return address on the stack.

Mike.
 
Thanks Motion and Pommie for your comments.

motion said:
Your code will fail because the instruction "incf PCLATH" does a read-modify-write but PCLATH is write-only.

This is exactly my concern that changing Microchip's code would results in such "Gotcha", which led me into investigating deeper the operation of PCLATH. I searched the net and I found the following:

1. My same code has been created and used by others years ago, apparently without any problem. The incf PCLATH,F is used in all those codings.

2. Some codes use BCF and BSF on the PCLATH too.

So Pommie is correct about that PCLATH can be incremented. However, I must thanks Motion again for his insight and valid concern. I have not considered such issues myself.
 
Much better solution for the 16F877

In the 16F877, the registers destined to manage EEprom data allow you to address anything along the program memory.

I used that and never bothered with tables again. Simple as that!

In my last five applications, all text to LCD traffic is based on that.

RTFM and you will see.
 
Re: Much better solution for the 16F877

atferrari said:
I used that and never bothered with tables again. Simple as that!

Yes, it is an alternative method of storing data in program memory. You can also pack two 7-bit ASCIIs in one word so it is also very efficient too.

It is much much easier to setup several registers and then wait for the data. Definitely a better way to go.

Only point is it can't be used on PICs like 16F628A whereas table lookup works on all PICs. However, it will work on 16F88 and all the 16F87X PICs.
 
Sorry for my mistake. It's been a long time since I've used a middle range PIC. I had long since upgraded to the PIC18 family because of the banking switching scheme which you should always be on the lookout as it could produce some very hard to find bugs. I don't recall having used PCLATH by reading from it. I may have however but I was just too lazy to check it out.
 
Motion (and gang),

Speaking of 18F' devices and tables -- you can perform some neat tricks using the Stack Pointer...

Here's a PutString routine I wrote for printing in-line strings using TBLPTR and the stack... I patted myself on the back for coming up with the idea for several months until I stumbled across a very old example of the same concept buried on PICList (grin)...

Regards, Mike

Code:
;
; _PutStr macro
;
_PutStr MACRO   str             ; print in-line string macro
        rcall   PutStr          ;
        db      str,0
        ENDM
;
; _PutStr Macro example
;
        _PutStr "K8LH Az/El Controller 1.041123\n\n\r"
;
;******************************************************************
;
;  print the in-line string using Stack Pointer & TBLPTR
;
PutStr  movff   TOSH,TBLPTRH    ; copy SP address to TBLPTR
        movff   TOSL,TBLPTRL    ;
        clrf    TBLPTRU         ;
PutNxt  tblrd   *+              ; get character at SP address
        movf    TABLAT,W        ; last character (00)?
        bz      PutXit          ; yes, exit
        rcall   Put232          ; else, print character
        bra     PutNxt          ; do another
PutXit  btfsc   TBLPTRL,0       ; odd address?
        tblrd   *+              ; yes, fix SP (make it even)
        movf    TBLPTRH,W       ;
        movwf   TOSH            ; update the return stack
        movf    TBLPTRL,W       ;
        movwf   TOSL            ;
        return                  ;
;
;******************************************************************
 
Hi Mike,

Had been using in-line parameters passing via stack for ages in 8031 programming so missed it much when I found out the stack of PIC16 is only 8 deep and there is no POP/PUSH operations.

With the 18F devices once again the above are available so no more table lookup to do. In-line parameter passing also make the asm code much easier to code and read.
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top