The table itself is a sequence of retlw instructions, which put a value into W and return. (dt and related directives are just assembler shorthand for inserting many retlws.)
A first try at implementing a table lookup thus looks like this:
movlw TABLE_BASE # Get the address of index zero
addwf index, w # Add the table index to the address
movwf PCL # Jump to that address
TABLE_BASE:
dt "012...
However, this code sequence has significant limitations. Recall that PCL is only an 8-bit wide register, while the PIC16F8?7's program counter is 13 bits wide. This means that when a computed jump is made by modifying PCL, the remainder of the new program counter comes from the bottom 5 bits of PCLATH. If PCLATH is 0x00, then movwf PCL can only jump to 0x0000-0x00FF: the first 256 words of program memory.
If we want to be able to put tables anywhere, then we need to fix PCLATH as well:
movlw HIGH(TABLE_BASE) # Get the top byte of the address of index zero
movwf PCLATH # Set up the top byte of the jump address
movlw TABLE_BASE # Get the bottom byte of the address of index zero
addwf index, w # Add the table index to this address
movwf PCL # Jump to PCLATH:PCL+index
TABLE_BASE:
dt "012...
This code still has a potential problem, however. If the table crosses a 256-byte boundary, then the correct value for PCLATH is different for lookups on either side of the boundary, and we need to correct for this:
movlw HIGH(TABLE_BASE) # Get the top byte of the address of index zero
movwf PCLATH # Set up the top byte of the jump address
movlw TABLE_BASE # Get the bottom byte of the address of index zero
addwf index, w # Add the table index to this address
btfsc STATUS, C # If we overflowed, then...
incf PCLATH, f # ...increment the top byte of the jump address
movwf PCL # Jump to PCLATH:PCL+index
TABLE_BASE:
dt "012...
This technique will work for any table with 256 or fewer entries.
If we want a table with more than 256 entries, we just have to extend the same approach to deal with an index with top and bottom bytes as follows:
movlw HIGH(TABLE_BASE) # Get the top byte of the address of index zero
addwf index_hi, w # Add the top byte of the table index
movwf PCLATH # Set the top byte of the address
movlw TABLE_BASE # Get the bottom byte of the address of index zero
addwf index_lo, w # Add the bottom byte of the table index
btfsc STATUS, C # If we overflowed, then...
incf PCLATH, f # ...increment the top byte of the jump address
movwf PCL # Jump to PCLATH:PCL+index
TABLE_BASE:
dt "123...
Comment
Remember that the last thing a table does is retlw the lookup value, meaning you need to call the table lookup routine for it to do what you expect. Hence you'd have to use the macro as follows:
ConvertBcdToAscii:
call_table TableBcdToAscii
TableBcdToAscii:
dt "0123456789"
SomeFunction:
...
movf some_char, w
call ConvertBcdToAscii
call LcdWrite
I suppose the macro would save you typing in the table lookup function.
I am neither a current AER201 student nor a TA, and my name is not actually Jack Sparrow.
Wait. Is your name actually Jack Sparrow? I assumed for a while that it was a fake name used by an AER201 student, but your posts seem to indicate the you are a TA. Disney ripped off your name.
More relevant to the post, this code would be more useful if it were a macro (I haven't tested this):
call_table macro TABLE_BASE
movlw HIGH(TABLE_BASE) # Get the top byte of the address of index zero
addwf index_hi, w # Add the top byte of the table index
movwf PCLATH # Set the top byte of the address
movlw TABLE_BASE # Get the bottom byte of the address of index zero
addwf index_lo, w # Add the bottom byte of the table index
btfsc STATUS, C # If we overflowed, then...
incf PCLATH, f # ...increment the top byte of the jump address
movwf PCL # Jump to PCLATH:PCL+index
© 2024 Created by PML. Powered by
You need to be a member of Personal Mechatronics Lab to add comments!
Join Personal Mechatronics Lab