Searching \ for '[PIC] Better 16F690 Table Lookup Algrorithms?' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: techref.massmind.org/techref/microchip/memory.htm?key=table
Search entire site for: 'Better 16F690 Table Lookup Algrorithms?'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] Better 16F690 Table Lookup Algrorithms?'
2006\03\23@142911 by Mike Ervin

picon face
I've just gotten into PIC development using a 16F690.  All of my development
is
in assembler.  I'm putting together a bit-map table for character
generation.
I use the character that I want generated to look up it's bit-map info in
the table.
Since I store the table in program memory, I need a method to index into
the table.  App note an556 (see below) recommends using an "retlw K"
instruction
to return the table value.  This does work, however, it requires two bytes
per
table entry.  Since my table is close to 1k bytes, this consumes an
additional 1k bytes
of program memory.
Has anyone found a better solution?

Thanks,
Mike

Example 1:
 .
 .
 movlw    offest
 call         Table
 .
 .
Table:
 addwf    PCL,F    ;add offset to pc to generate a computed goto

 retlw     'A'        ;return the ASCII char A
 retlw     'B'        ;return the ASCII char B
 retlw     'C'        ;return the ASCII char C
 .
 .


2006\03\23@154030 by Bob Axtell

face picon face
The 16F690 has the capability of reading and storing tables as 14-bit
values in PGM memory, rather
than in retlw tables. In that case, your 1K table would require 1K
14-bit words. If your table values will
fit into 14 bits, this is very efficient. To do this in RETLW xx mathod
will require 2K + some overhead.

I'm not sure what your application is , but I have built  strain-guage
sensors based on the F876 calibrated
in exactly this way. In this application, pgm space was tight, but the
width of the data needed was only
10 bits, whereas I had 14 bits to work with. What I did was to squeeze
the table length to 5/7 of its size.
Here's how:

Write an algorithm that will read in 5 14-bit words, and pump out 7
10-bit table values. This is because
5 * 14 = 70, and 7 * 10 = 70, so there will be no losses. This algorithm
will be called in order to obtain
the correct 10-bit table value in real time.

When you have decided what needs to be loaded into the table (the
sensor/PIC PCB is subjected to
tests at critical points so a table can be created) then create an
algorithm that takes 7 10-bit values
and squeezes then into 5 14-bit values. When the "1K Table" is done, it
only took 5/7*1024 bytes or
about 732 words

--Bob  



Mike Ervin wrote:

{Quote hidden}

--
Note: To protect our network,
attachments must be sent to
spam_OUTattachTakeThisOuTspamengineer.cotse.net .
1-520-850-1673 USA/Canada
http://beam.to/azengineer

2006\03\23@162727 by Jan-Erik Soderholm

face picon face

Mike Ervin wrote:
> App note an556 (see below) recommends using an "retlw K"
> instruction to return the table value.  This does work,
> however, it requires two bytes per table entry.

No, it requires 1 *word*, which is not = 2 bytes.


Then Bob Axtell wrote :

> The 16F690 has the capability of reading and storing tables
> as 14-bit values in PGM memory, rather than in retlw tables.
> In that case, your 1K table would require 1K 14-bit words.
> If your table values will fit into 14 bits, this is very efficient.

OK, 1 byte in each word of flash.

> To do this in RETLW xx mathod
> will require 2K + some overhead.

This I don't understand. 2K of what ? Words or bytes ?
A RETLW table *also* stores 1 byte in each word of flash...


Now, maybe the table value actualy a 7-bit value ?
As when using 5x7 dot displays ?
In that case you might store 2 table entries in each
14-bit flash word.

Regards,
Jan-Erik.



2006\03\23@171727 by Mike Ervin

picon face
Yes, you're right, it does use 1 "word" (14-bits) and not
two bytes (8-bit bytes).  I was wondering why I kept losing
the high-order two bits when I used the following
statements in code section:

   db 0x80

kept showing up as 0x00.  My mistake :-)

I can probably get by with 7x8 characters, so I'll try
squeezing two of those in each program "word" :-)

   db 0x7F,...

But I am still not clear on how to access the table data in program
memory without using the "retlw K" instruction.

It would be nice if I could do something like:

 movfw  <program memory location>

Thanks Bob/Jan-Eric!


{Quote hidden}

>

2006\03\23@182316 by Bob Axtell

face picon face
Jan-Erik Soderholm wrote:

{Quote hidden}

2K of code words. a " RETLW XX" is a full code word. He said that
he needed two bytes for each table entry. If he did it using RETLW XX
he would need 2K code words, plus the overhead of "addwf pcl,f". Right?

>Now, maybe the table value actualy a 7-bit value ?
>As when using 5x7 dot displays ?
>In that case you might store 2 table entries in each
>14-bit flash word.
>  
>
er, well it was never made clear how wide his table entry was. So
by example, I showed him how to compress 10bit table entries so
that less code space could be taken.

>Regards,
>Jan-Erik.
>
>
>
>  
>


--
Note: To protect our network,
attachments must be sent to
EraseMEattachspam_OUTspamTakeThisOuTengineer.cotse.net .
1-520-850-1673 USA/Canada
http://beam.to/azengineer

2006\03\24@024412 by Michael L. Ervin

picon face
Ok,
I've concluded that there is no "easy" way to set up a bit-map table using
"program memory".
So, I've done what the app note an556 suggests.  Here's a snippet of the
code that I've
put together for a table lookup.  It requires twice the memory necessary,
but it does get
the job done :-)  And there's a LOT of processing necessary to extract each
data byte
from "program memory".
Are there any other PIC processors that would be better suited for this
application?
It would be interesting to see how a "c" program handles this :-)

Thanks for the feed back!
Mike

; =======================================================================

WorkW     res 2      ; work variable
ASCIIch    res 1      ; ASCII character to process
ASCIImo  res  1      ; ASCII bit map offset
ASCIIbm  res  8      ; 8x8 bit ASCII character bit map


PROG CODE   ; Set the start of code from 16f690.lkr script

; ASCII Character table processing.  This routine determines the progam
; memory address and offset from that address to extract the 8-byte bit
; map definition of the ASCII character.
;
; Inputs: ASCIIch = the character to process
;
; Outputs:  ASCIIbm[0]...ASCIIbm[7] contains the character map

ASCIIbitMap
  clrf       ASCIImo           ; set bit map offset to zero
  call       bitMapWork
  movwf  ASCIIbm+0

  incf       ASCIImo
  call        bitMapWork
  movwf  ASCIIbm+1

  incf       ASCIImo
  call        bitMapWork
  movwf   ASCIIbm+2

  incf        ASCIImo
  call        bitMapWork
  movwf   ASCIIbm+3

  incf        ASCIImo
  call         bitMapWork
  movwf   ASCIIbm+4

  incf        ASCIImo
  call         bitMapWork
  movwf   ASCIIbm+5

  incf        ASCIImo
  call         bitMapWork
  movwf   ASCIIbm+6

  incf        ASCIImo
  call         bitMapWork
  movwf    ASCIIbm+7

  return

bitMapWork

  movfw    ASCIIch
  movwf    WorkW
  movlw    ' '
  subwf    WorkW
  clrf        WorkW+1

  bcf        STATUS,C
  rlf          WorkW
  rlf          WorkW+1

  bcf         STATUS,C
  rlf           WorkW
  rlf           WorkW+1

  bcf          STATUS,C
  rlf            WorkW
  rlf            WorkW+1

  movfw     WorkW+1
  addwf      PCLATH
  movfw     WorkW
  addwf      ASCIImo,W
  addwf      PCL

; ' ' space character

  dt     b'00000000'    ; each "dt" produces an RETLW <value> which
requires 14 bits per 8 bit table entry
  dt     b'00000000'
  dt     b'00000000'
  dt     b'00000000'
  dt     b'00000000'
  dt     b'00000000'
  dt     b'00000000'
  dt     b'00000000'

  ; '!' exclamation point

  dt     b'00110000'
  dt     b'01111000'
  dt     b'01111000'
  dt     b'00110000'
  dt     b'00110000'
  dt     b'00000000'
  dt     b'00110000'
  dt     b'00000000'

  ; '"' double quote

  dt     b'01101100'
  dt     b'01101100'
  dt     b'01101100'
  dt     b'00000000'
  dt     b'00000000'
  dt     b'00000000'
  dt     b'00000000'
  dt     b'00000000'

2006\03\24@040701 by William Chops Westfield

face picon face

On Mar 23, 2006, at 11:44 PM, Michael L. Ervin wrote:

> Are there any other PIC processors that would be better
> suited for this application?

The PIC18 family has byte-addressable program memory and the TBLRD
(table read) instruction, which should help quite a bit

> It would be interesting to see how a "c" program handles this :-)
>
A C program can handle the algorithms fine.  C handles multiple
memory spaces less well.  Whether the compiler can produce
useful code out of something readable is another matter!

I think your code has quite a bit of room for improvement.
Have you looked here:

www.piclist.com/techref/microchip/tables.htm
http://www.piclist.com/techref/microchip/bigtable.htm

If I can translate your code into pseudo-C, you're doing:

char asciibm[8];        /* Output bitmap */

asciibitmap(char ASCIIch)
{
    asciibm[0] = bitMapWork(ASCIIch, 0);
    asciibm[1] = bitMapWork(ASCIIch, 1);
       :
    asciibm[7] = bitMapWork(ASCIIch, 7);
    asciibm[8] = bitMapWork(ASCIIch, 8);
}

char bitMapWork(char asciichar, char row)
{
    char * (bitmapentry)(void);  /* pointer to a function */

    bitmapentry = 8 * asciichar;  /* compute offset to start */
       bitmapentry += row;                          /* Add in the row offset */
       bitmapentry += TABLESTART;          /* table beginning */
       return *(bitmapentry)();          /* call code via computed pointer. */
}

This being an 8bit micro, the multiplication and math on the "bigger
than 8 bit" pointer is a bit painful.

I think you should "refactor" the code more like:

asciibitmap(char ASCIIch)
{
    char *(bitmapentry)(void);  /* pointer to function */

       bitmapentry = bitMapTop(ASCIIch);
    for (i=0; i < 8; i++)
          asciibm[i] = *(bitmapentry++)();
}
<mumble> bitMapTop(asciichar)
{
       /* return pointer to first row for a character */
    return TABLESTART + (8 * asciichar);
}

THat is; only compute the pointer to the start of the bitmap for
your character once, rather than 8 times.  If you arrange your
bitmap table a bit carefully, an single character's bitmap data
will never span a page (or even 256 byte) boundry, and the increment
of the pointer for each "row" becomes easy.

OTOH, many applications that use bitmaps will end up needing row 0
of multiple characters before they're ready for row 1 of the first
character, which is what your existing bitMapWork function does
reasonably well (assuming it's correct; I didn't really check),
so optimizing the retrieval of the entire bitmap may not be useful.

If you can use a 8x7  bitmap instead of 8x8, you can use the
special flash read instructions and cut your table size in half,
and the code will be basically similar.  The flash read is described
in section 10 of the 690 manual...

BillW

2006\03\24@073845 by Bill & Pookie

picon face
> Write an algorithm that will read in 5 14-bit words, and pump out 7
> 10-bit table values

How do you get them in program memory with assembler, how do you read them
and how do you break them out?

Bill

{Original Message removed}

2006\03\24@092401 by Bill & Pookie

picon face
Sounds like you are writing code to display the complete ASCII character set
on a dot matrix display.  What does the display require in regards to data?
More than one line of characters?  Do you send it the blank pixels between
characters and above' lines?

Are you receiving characters from outside that you will display?

And the big question, do you really need the ability to display the complete
ASCII character set?   If you are getting characters from outside, you may
want to translate them to your own internal character set so that you will
not have any invalid characters characters in and being acted upon.

For displaying, your character set could have hex 0 to 9 an characters 0 to
9.  and to display a 3 would consist of

dspzero
   movlw H:91'
   call      display
   movlw  H'91'
   call   display
  .------

And the character A could be translated to decimal 10, BE to decimal 11.
And if you have a few words and phrases you wish to display , "VOLTS",
"HIGH" and "DANGER WILL ROBERTSON!" could be treated as one character with a
lot of bits to display.

The computed 'goto' could go to (another goto) the character , word or
phrase you desired to display.

;  W contains character code of character, word or phrase
    addwf    PCL,F    ;add offset to pc to generate a computed goto
   goto  dspzero
   goto  dspone
--------------
  goto  dspvolts
  goto  dspdangerwr

Just a thought.

Bill

{Original Message removed}

2006\03\24@123255 by Robert Ammerman

picon face
The trick is to isolate the way the data is physically stored from the way
the application accesses it. For example, you could access the data, up to
16 bits at a time, using a function like:

   unsigned int16 get_pgm_data( void (*base_address)(void), unsigned int16
bitpos, unsigned int8 numbits )

Where:
   base_address is a code address of the area containing the code. The
funny syntax lets "C" think of it as a function pointer so that it is
relative to code memory.
   bitpos is a bit position within the code memory, starting at bit 0.
   numbits is the number of bits to return.

Then the 'get_pgm_data' routine would handle the job of actually grabbing
the data from code memory regardless of its alignment.

An application would then just have to do things like:

#define PIXELSPERROW 12
#define ROWSPERCHAR 10
#define PIXELSPERCHAR ((PIXELSPERROW) * (PIXELSPERCHAR))


   charstart = charcode * PIXELSPERCHAR;    // determine starting location
of character

   for (i = 0; i < ROWSPERCHAR; i++)
   {
         x = get_pgm_data( pixel_data, charstart, PIXELSPERROW);
         <process x>
         charstart += PIXELSPERROW;
   }

And, as I mentioned before, getting the data into the correct bit-packed
form can be done by using Excel to create the assembly language source code.
I have also done this by using rather elaborate macros in MPASM, and in a
few cases by writing custom conversion programs to create the MPASM source.

Bob Ammerman
RAm Systems


2006\03\24@123646 by Michael L. Ervin

picon face
Thanks for the feedback!  I think the "flash read" you mentioned below will
help
a lot.  I can get by with 8x7 bitmap which will reduce the table size
considerably.

Thanks,
Mike

{Original Message removed}

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