![]() |
![]() |
![]() |
|
|
|||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
|
|
Thread Tools | Display Modes |
|
|
(permalink) |
|
Experienced 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
__________________
L.Chung |
|
|
|
|
|
(permalink) |
|
Super Moderator
|
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...
__________________
"I share, thus I am" Jay.slovak Read this! ICD2 Clone Best PIC/DsPIC Bootloader Read my Inchworm ICD2 review! |
|
|
|
|
|
(permalink) | |
|
Experienced Member
|
Quote:
The safest way is to ask in an open forum as there are many experienced code writers around.
__________________
L.Chung |
|
|
|
|
|
|
(permalink) |
|
Experienced Member
|
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.
__________________
"Having to do with Motion Control" |
|
|
|
|
|
(permalink) | |
|
Experienced Member
|
Quote:
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. |
|
|
|
|
|
|
(permalink) |
|
Experienced Member
|
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. |
|
|
|
|
|
(permalink) | |
|
Experienced Member
|
Thanks Motion and Pommie for your comments.
Quote:
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.
__________________
L.Chung |
|
|
|
|
|
|
(permalink) |
|
Experienced Member
|
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.
__________________
Agustín Tomás In theory, there is no difference between theory and practice. In practice, however, there is. |
|
|
|
|
|
(permalink) | |
|
Experienced Member
|
Quote:
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.
__________________
L.Chung |
|
|
|
|
|
|
(permalink) |
|
Experienced Member
|
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.
__________________
"Having to do with Motion Control" |
|
|
|
|
|
(permalink) |
|
Experienced Member
|
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 ;
;
;******************************************************************
|
|
|
|
|
|
(permalink) |
|
Experienced Member
|
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.
__________________
L.Chung |
|
|
|