Searching \ for 'AN556 and long look-up tables' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/mems.htm?key=table
Search entire site for: 'AN556 and long look-up tables'.

Truncated match.
PICList Thread
'AN556 and long look-up tables'
2000\05\20@103820 by David Thompson

flavicon
face
Hi guys,

Firstly, don't scream.. I HAVE read the datasheets!. My table reading
subroutine is based on the final example in AN556 "Implementing a Table
Read" and can be used across page boundaries and be located anywhere in
memory... BUT!... will not work if the table itself is longer than 256
bytes. This is because the table element offset is passed in w (8 bits) and
then used in the calculation for the program counter. Trying to access
elements that start beyond an offset of 256 bytes won't work.

I could make a new separate table, but would prefer to keep it all together.
Based on the app note from Microchip, I can't see a simple way to do this
with one table. This particular example (example 5 in AN556) is already
complicated, and would be a mess if I try to make it cater for such things.

Has anyone posted a lookup table reader that can access defined elements in
a table longer than 256 bytes?. Weird thing is that AN556 does not
specifically warn of this. Maybe I'm doing something wrong... Hopefully one
of you can help.

My application is listed in part below. Firstly, the top of the table looks
like this. I have the modem strings arranged with the string length first,
then the string. This is the best way for this particular application.

;**********************************************************
;* Data tables
;**********************************************************
command
       movwf   PCL                                     ;Update PCL with computed value
table_base                                              ;Table start reference
off_hook
       dt      0x07,"AATDT;",0x0d
hang_up
       dt      0x05,"AATH",0x0d
modem_reset
       dt      0x05,"AATZ",0x0d
dummy_dial
       dt      0x17,"AATM2S07=48DT,xxxxxxxx",0x0d
;
You can call up one of these modem strings by simply doing this...

       movlw   modem_reset-table_base          ;Calculate table offset for reset string
       call    send_command
;
And the big daddy of a table reader/modem string sender...

;*********************************************************
;* Send modem command string - called with table offset in w
;*********************************************************
send_command
       movwf   table_offset            ;Save table offset
       movlw   LOW table_base          ;Get low 8 bits of table address
       addwf   table_offset,f          ;8-bit add to get abs location of string, could
overflow...
       movlw   HIGH table_base         ;Get high 5 bits of table address
       btfsc   STATUS,C                        ;Did that last add cross page boundary?
       addlw   1                               ;Yes, roll over into next page
       movwf   PCLATH                  ;Preload high address
       movf    table_offset,w          ;Update calculated offset
get_length
       call    command                 ;Get first byte (string length)
       movwf   msg_length                      ;Save message length
send_next
       movlw   1                               ;Increment table offset... carefully
       addwf   table_offset,f
       movlw   HIGH table_base
       btfsc   STATUS,C                        ;Crossed page boundary when incremented?
       addlw   1                               ;Roll over into next page
       movwf   PCLATH                  ;Preload high address
       movf    table_offset,w          ;Update offset
       call    command                 ;Jump to table with offset in w...
loop_com
       btfss   PIR1,TXIF                       ;Check if txreg empty
       goto    loop_com                        ;Loop until free
;
wait_CTS                                        ;Hardware flow control. CTS is normally LOW
       btfsc   PORTB,CTS                       ;Are we clear to send?
       goto    wait_CTS                        ;If CTS = HIGH, modem is busy
;
gie_tx
       bcf     INTCON,GIE                      ;Disable interrupts, dammit!
       btfsc   INTCON,GIE
       goto    gie_tx

       movwf   TXREG                           ;Send byte to modem
       bsf     INTCON,GIE                      ;Re-enable interrupts
       decfsz  msg_length,f    ;Decrement length, if not zero
       goto    send_next                       ;Keep going...
       return

2000\05\20@184429 by Thorsten Klose

picon face
Someone posted a long look-up table example for a few
days, just result the piclist search engine.

Beside of this: Which chip are you using? If it is
a 16f87x, you can read out the code memory directly,
and together with the "da" directive of MPASM it
is very simple to store ASCII data in backed byte
format, which makes your code much smaller! :)

Best Regards, Thorsten.

--
_____________________________________________
_/ uC-Stuff for MIDI at http://go.to/uCApps /_______
/ Music is aesthetisized frequency (Klaus Schulze) /
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

2000\05\20@184442 by paulb

flavicon
face
David Thompson wrote:

> ;**********************************************************
> ;* Data tables
> ;**********************************************************

 ; *** Reserve TWO bytes for table_offset ***

> command
         movlw   table_offset    ;Get high 5 bits of table address
         movwf   PCLATH          ;Preload high address
;   PCLATH must be set *in* the subroutine, not *before* it
         movf    table_offset+1,w  ;Transfer low address
         movwf   PCL             ;    to PCL

 ; Data tables (may be anywhere in memory)
> off_hook
>         dt      0x07,"AATDT;",0x0d
> hang_up
>         dt      0x05,"AATH",0x0d
> modem_reset
>         dt      0x05,"AATZ",0x0d
> dummy_dial
>         dt      0x17,"AATM2S07=48DT,xxxxxxxx",0x0d
> ;

 macro   send_command    where
         movlw   HIGH where      ;table high address
         movwf   table_offset
         movlw   LOW where       ;table low address
         call    do_send
         endm

> You can call up one of these modem strings by simply doing this...

         send_command    modem_reset     ;reset string

> ;*********************************************************
> ;* Send modem command string - called with table offset in w
> ;*********************************************************
 do_send
         movwf   table_offset+1  ;Save table offset
         call    command         ;Get first byte (string length)
         movwf   msg_length      ;Save message length
 send_next
         incfsz  table_offset+1,f  ;Increment table offset
         incfsz  table_offset,f  ;   including high byte
         call    command         ;Jump to table
> loop_com
>         btfss   PIR1,TXIF       ;Check if txreg empty
>         goto    loop_com        ;Loop until free
> ;
> wait_CTS                        ;Hardware flow control. CTS norm LOW
>         btfsc   PORTB,CTS       ;Are we clear to send?
>         goto    wait_CTS        ;If CTS = HIGH, modem is busy

> gie_tx
>         bcf     INTCON,GIE      ;Disable interrupts, dammit!
                                 ; But - why?
>         btfsc   INTCON,GIE
>         goto    gie_tx

>         movwf   TXREG           ;Send byte to modem
>         bsf     INTCON,GIE      ;Re-enable interrupts
>         decfsz  msg_length,f    ;Decrement length, if not zero
>         goto    send_next       ;Keep going...
>         return

 E&OE of course ;-)
--
 Cheers,
       Paul B.

2000\05\22@142156 by rleggitt

picon face
Hi David, something like this should work for arbitrary table of any
length located anywhere in the program space. -- Rich

               ...
               movlw high string       ; point to a string
               movwf look_hi           ; in reality, a macro...
               movlw low string
               movwf look_lo
               call process            ; go process it
               ...

; subroutine to process string at look_hi/look_lo
process         call lookup             ; get a byte (this is the magic)

               ; here, do something with byte in W
               ; also, return if end of string
               ; otherwise...

               goto process            ; do it again

; Jump to address in look_hi/look_lo, which presumably is an RETLW.
; Note pointer post increment.
; Equivalent to: W=*look_ptr++
lookup          movf look_hi,w          ; set PCLATH
               movwf PCLATH
               movf look_lo,w          ; and get PCL
               incf look_lo,f          ; but post inc
               skpnz
               incf look_hi,f
               movwf PCL               ; ok, now jump


On Sun, 21 May 2000, David Thompson wrote:

> Hi guys,
>
> Firstly, don't scream.. I HAVE read the datasheets!. My table reading
> subroutine is based on the final example in AN556 "Implementing a Table
> Read" and can be used across page boundaries and be located anywhere in
> memory... BUT!... will not work if the table itself is longer than 256
> bytes. This is because the table element offset is passed in w (8 bits) and
> then used in the calculation for the program counter. Trying to access
> elements that start beyond an offset of 256 bytes won't work.

More... (looser matching)
- Last day of these posts
- In 2000 , 2001 only
- Today
- New search...