PIC Microcontoller Memory Method

Big Table lookups

Today I'm going to discuss how to read data from a table that crosses a 256 byte boundary.

The easiest and fastest way to do this is to use special "table read" instructions. See table lookups for details. [FIXME: should I move that information from there to here ?]

But some PIC processors don't have those special "table read" instructions. Are we out of luck ? No. We can extend the 'computed GOTO/RETW-style' table so it can handle tables that cross a 256 byte boundary.

Tony Nixon says:

Table can access 1 to 8178 bytes (assuming max ROM of 8K)
 fcall Table
; will be returned here with data in W.
 ; Tony Nixon
 ; plus tweak from Dmitry Kiryashov [zews at AHA.RU]
Table movlw High(TStart)
 addwf OffsetH,W
 movwf PCLATH
 movlw Low(TStart)
 addwf OffsetL,W
 skpnc
 incf PCLATH,F
 movwf PCL ;computed goto with right PCLATH
 ; end of Table subroutine.
 ; ...
 ; 
 org 0x????
TStart Retlw d'0'
 Retlw d'255'
 Retlw d'9'
 ....
 etc

As an example of how to use it, say you want to output speech data at 5K samples per second. A simple R2R ladder is on PortB. The speech table has 3000 data points

 ; Tony Nixon
 ; modified by David Cary
;(macros go here)
; the fcall macro
; by Roger Froud of Amytech Ltd.
fcall	macro subroutine_name
	local here
	lcall subroutine_name ; set PCLATH correctly
	pagesel here ; set PCLATH correctly
here:
	endm
;(execution starts here)
Start clrf OffsetH
 clrf OffsetL
SoundLoop ; 200uS loop time = 5000 samples per second
 fcall Table
 movwf PORTB
 ;[FIXME: wait the remaining 200 microseconds]
 incf OffsetL ; add 1 to data pointer
 skpnz
 incf OffsetH
NoUp movlw Low(d'3000')
 xorwf OffsetL,W
 skpnz
 goto SoundLoop
 movlw High(d'3000')
 xorwf OffsetH,W
 	skpnz
 goto SoundLoop
 goto Start
;
; SOUND DATA TABLE 3000 ELEMENTS
;
Table movlw High(TStart)
 addwf OffsetH,W
 movwf PCLATH
 movlw Low(TStart)
 addwf OffsetL,W
 skpnc
 incf PCLATH,F
 movwf PCL ;computed goto with right PCLATH
 ; end Table subroutine
TStart DT "Hello. I'm Mr Ed"
; plus another 2984 data points
 end

PS: the text won't sound like that coming from PORTB ;-)

PPS :if you want an easy way to create a 3000 point data table ready for MPASM see

http://www.bubblesoftonline.com/demo/dtimg.html

Scott Dattalo says:

;*******************************************************************
;write_string
;
; The purpose of this routine is to display a string on the LCD module.
;On entry, W contains the string number to be displayed. The current cursor
;location is the destination of the output.
; This routine can be located anywhere in the code space and may be
;larger than 256 bytes.
;
; psuedo code:
:
; char *string0 = "foo";
; char *string1 = "bar";
;
; char *strings[] = { string0, string1};
; char num_strings = sizeof(strings)/sizeof(char *);
;
; void write_string(char string_num)
; {
; char *str;
;
; str = strings[string_num % num_strings];
;
; for( ; *str; str++)
; LCD_WRITE_DATA(*str);
;
; }
;
; Memory used
; buffer2, buffer3
; Calls
; LCD_WRITE_DATA
; Inputs
; W = String Number
;
write_string
 ; Make sure the input string_num is in range.
 andlw WS_TABLE_MASK
 ; get pointer into the ws_table array:
 ; [w,buffer3] = wstable + 2*string_num
 movwf buffer3
 addwf buffer3,w
 ; [FIXME: the carry from doubling w is lost,
 ; limiting us to a maximum of 128 strings --
 ; add code here to handle up to 256 strings]
 addlw LOW(ws_table) ; carry set ...
 movwf buffer3
 movlw HIGH(ws_table)
 skpnc ; ... carry used.
 addlw 1
 ; now [w,buffer3] points to the lo byte of the address of the string.
 movwf PCLATH
 ; now [PCLATH,buffer3] points to the lo byte of the address of the string.
 ; get lo byte of the address of the string
 movf buffer3,w
 call ws2
 ; buffer2 = lo byte of the address of the string
 movwf buffer2
 ; get hi byte of the address of the string
 ; (handle special case of ws_table starting on odd address AND
 ; ws_table crossing a 256 byte page boundary)
 incf PCLATH,f
 incfsz buffer3,w
 decf PCLATH,f
 call ws2 ;get the high word (of the offset)
 ; now we have address of the start of the string in
 ; [w, buffer2]
 movwf PCLATH ;
ws1: ;Now loop through the string
 movf buffer2,w
 call ws2
 andlw 0xff
 skpnz ;If the returned byte is zero,
 return ;we've reached the end of the string
 ; exit point of write_string subroutine
 ; WARNING: we're holding the hi part address of the start of string
 ; in PCLATH right now --
 ; -- so the LCD_WRITE_DATA subroutine,
 ; any subroutines it calls, and the actual string data
 ; must be on the same 2048 byte page.
 ; FIXME: remove this silly limitation.
 call LCD_WRITE_DATA
 incf PCLATH,f ;Point to the next character in the
string
 incfsz buffer2,f
 decf PCLATH,f
 goto ws1
 ; end of write_string subroutine
ws2
 movwf PCL
; WS_TABLE_MASK must be one less than the number of entries in the ws_table.
#define WS_TABLE_MASK 3
; #define WS_TABLE_MASK 127 ; use this when you have 128 strings
; The first part of the table contains pointers to the start of the
; strings. Each string has a two word pointer for the low
; and high bytes.
; no restrictions on table start location
; the number of entries in the ws_table must be a power of 2 ...
; 2, 4, 8, 16 ... up to 256 strings.
; If you only need, say, 5 strings, put 8 entries in the ws_table.
; It's OK for several entries in the ws_table
; to point to the same string.
ws_table:
 retlw LOW(string0)
 retlw HIGH(string0)
 retlw LOW(string1)
 retlw HIGH(string1)
 retlw LOW(hello_string)
 retlw HIGH(hello_string)
 retlw LOW(hello_string)
 retlw HIGH(hello_string)
; no restrictions on string start location
string0: dt "GPSIM WROTE THIS",0
hello_string: dt "Hello world."
string1: dt "A STRING ON ROW 2",0

also:

David A Cary of Motorguide Pinpoint Says:

Someone mentioned

SoundLoop:
 ...
 incf OffsetL ; add 1 to data pointer
 btfsc STATUS,C
 incf OffsetH

but my little cheat sheet claims that `incf' only affects the Z bit, not the C bit. Is my cheat sheet leaving something out ? Or is there a bug in this code ? Or am I missing something ? SoundLoop: ... incf OffsetL ; add 1 to data pointer btfsc STATUS,Z ; also known as skpnz incf OffsetH

The heavy use of btfsc STATUS,C ; also known as skpnc elsewhere on this page looks OK, because they follow the ``addwf'' or ``addlw'' instructions, which do affect the carry bit. -- David Cary

[FIXME: Is there a page that lists "skpnz" "skpnc" etc. other than compcon.htm ? ]

Comments:

Interested:

See:

Guy Griffin Says:

PCLATH is only modified explicitly, i.e. the PIC never changes it. Multiple computed GOTOs must set PCLATH appropriately before each PCL write, otherwise you'll get a jump to an unexpected address.

For example, a moving-message display: a small table lookup uses ADDWF PCL,f to returns the next ASCII code from a series. Then a large page-crossing table returns a column of pixels for display, probably modifying PCLATH in the process. This works OK the first iteration only - as the little table doesn't setup PCLATH, it gets implicitly loaded into PC the next time around... resulting in a jump to some unknown place in the middle of the code, and a large headache to debug.
+
file: /Techref/microchip/bigtable.htm, 10KB, , updated: 2006年4月27日 12:39, local time: 2025年9月1日 08:54, owner: DAV-MP-E62a,
40.74.122.252:LOG IN

©2025 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it! / MAKE!

<A HREF="http://techref.massmind.org/techref/microchip/bigtable.htm"> PIC Microcontoller Memory Method Big Table lookups</A>

After you find an appropriate page, you are invited to your to this massmind site! (posts will be visible only to you before review) Just type a nice message (short messages are blocked as spam) in the box and press the Post button. (HTML welcomed, but not the <A tag: Instead, use the link box to link to another page. A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.


Link? Put it here:
if you want a response, please enter your email address:
Attn spammers: All posts are reviewed before being made visible to anyone other than the poster.
Did you find what you needed?

Welcome to massmind.org!

Welcome to techref.massmind.org!

.

AltStyle によって変換されたページ (->オリジナル) /