Making Program Code Space your playground...


Results 1 to 16 of 16

Threaded View

  1. #1
    Join Date
    Jul 2003
    Posts
    2,358

    Default Making Program Code Space your playground...

    Whilst this has also been posted to the piclist here it is for reference - and also that several hours after posting it's still somewhere 'lost in space'.

    >
    > Can you provide a quick example of writing data to
    > code space and reading it back?
    >

    This is relatively simple... and there's many ways of doing this... so I'll keep it short with just one method...

    The PBP command to read data from codespace is READCODE address,data.

    For example 16F pics that support READCODE like the 16F876, and the 16F877 (amongst others) allow you to save and extract 14-bits of data per memory location. For those that haven't got enough fingers and toes to do the math, that gives you a range of 0-16383. Let's call this PCWord (for Program Code Word rather than a real word which is 16 bits). Naturally you define 'data' as a word if you want to grab all 14-bits, and if you define it as a byte you just get the lower 8 bits. The 'address' is also a WORD (a real 16-bit variety) and is any spot in valid codespace.

    WRITING to codespace should be restricted, it's not as resilient as EEPROM and theoretically wears out quicker, but for use as sporadic storage or for giant Lookup tables, it saves on an external EEPROM if you're tight for cash or PCB Real-Estate. READING from codespace is unlimited, doesn't wear out your PIC, doesn't use any calories and can be used without restriction - so go do it.

    WRITECODE is the opposite to READCODE and allows you to write to those memory locations. But it's kinda wasteful having to use WRITECode to create a 1000 word table before having to use it. Whilst WRITECODE and READCODE are the equivalents of READ and WRITE on a bigger scale, what's missing is the equivalent of the DATA statement which allows you to preset those memory locations.

    For this we have to jump into some lines of Assembler which I'll teach you here...

    Let's say we wish to create a 1000 word table in Program space. First choose a memory location well away from your code. So an PIC16F876/877 has 8K (8192) words of Program Codespace. If we put our data table out of the way starting at address 7190, it means we can create a program that uses up to 7190 words. Any bigger and it risks overwriting our data table.

    Our Data table is created thus (note caps for CODE and DB)... and shove it at the end of your code... PLEASE NOTE that I am using PBP's Assembler mnemonics here, there are some variances for MPASM but the theory is the same.
    Code:
        Asm
        CODE 7190
        DB 254
        DB 1
        DB "Hey, Beautiful"
        DB 254
        DB 192
        DB "What's Cookin?"
        DB 0
        Endasm
    (Note: Here on this forum, the display above will corrupted and left-justified. The CODE and DB statements must be indented and must NOT start at column 1 in your code. The left-hand edge is reserved in Assembler for Labels ONLY.)

    This is the equivalent of sequentially storing...
    Code:
       $FE,$01,"Hey, Beautiful",$FE,$C0,"What's Cookin?",0
    Let's now read that data in and display it on our LCD... here's a couple of ways rolled into one demo program...
    Code:
        PCAddress var WORD
        PCData var BYTE
    
    DoitAgain:
        PCAddress=7190
        '
        ' Read & Display till we get a stop character
        '
    ReadCodeLoop:
        READCODE PCAddress,PCData
        If PCData>0 then
            LCDOut PCData
            PCAddress=PCAddress+1
            Goto ReadCodeLoop
            endif
        Pause 2000
        '
        ' Read a set number of locations
        ' (two in this case - to Clear the LCD)
        '
        For PCAddress=7190 to 7191
            READCODE PCAddress,PCData
            LCDOut PCData
            Next PCAddress
        Pause 1000
        Goto DoitAgain
        End
    (Download the accompanying pcode.txt file for a pretty example).

    There are a number of things you have to remember. So here's the rules of the game - don't disregard them or they'll come back and bite you...

    1. Don't spill your data out of available memory... you'll get stacks of compiler error messages anyway. Remember, be nice, leave some space for your program. Every PCWord you steal from Program Memory is one word less you've got available in programming.

    2. Remember how many data elements you've preset. If you've preset 1000 PCWords, don't access 1001 because it probably won't contain things relevant to your data table.

    3. When using WRITECODE, if you access the WRONG memory locations, you run the risk of corrupting your program code. Stick rigidly to the addresses for your data. Remember the golden rule of programming... "if you put it into memory, remember where you put it".

    The downside... OK there's no free lunch (unless you're buying it for me). No gain without pain, and this little niggle is significant...

    4. Whilst you can WRITECODE with 14 bits, and READCODE with 14 bits, you can't preset 14-bits with the assembler DB statement. You can ONLY preset 8 bits, and the upper 6 bits (remember 14-bits for our PCWord) will always be preset to %110100. Hey, I didn't write the assemblers - so don't lay this one on me. Consider the DB statement as standing for 'Data Byte'. BYTE being the appropriate thing to notice. So each 8-bit BYTE you store, gets saved as a 14-bit PCWord... example...

    You want to save a value of ONE...

    DB 1

    That memory location will actually contain in 14-bits...

    11010000000001

    You can however within your PBP Program do this...
    Code:
        MyWord var Word
        MyWord=1
        WRITECODE address,MyWord
    and that address will have in 14-bits...

    00000000000001

    (when reading or writing with WRITECODE and READCODE into/from a 16-bit word, the upper two bits should always be considered zero)...

    You might think that instead of using the DB statement, I'll go and use DW (Data Word rather than Data Byte)... but look what happens...
    Code:
        CODE 7190
        DW 1
    You would think you would get 00000000000001 stored into location 7190... but hey, they've thought of that and you actually get the lower 8-bits stored into location 7190, and the upper eight bits (yes of a whole 16-bit word) gets stored in location 7191. The upper six bits of both memory locations stubbornly still get preset to %110100. Like I said, don't lay this on me.

    Finally... if there is such a thing as 'finally'...

    5. Playing with the CODE directive (as in example CODE 7190), kinda screws the compiler reporting the true value of the words used in your program. If you need to know the actual size of your compiled program (useful to determine how much Program Code space it's used), just remove the Asm...Endasm section and compile. Drop it back in for your final program. Some folks will argue that the Asm...Endasm section should be lower down in your code and just jump over it. Sure you could do that. Personally I like to keep the data blocks that I'm tampering with well away from my Program Code.

    The appended file is a ready-to-run demonstrator. Go create and have fun.

    So I lied about keeping it short...

    Melanie
    Attached Files Attached Files
    Last edited by ScaleRobotics; - 30th October 2010 at 18:01. Reason: added a few code tags

Similar Threads

  1. Presetting Configuration Fuses (PIC Defines) into your Program
    By Melanie in forum FAQ - Frequently Asked Questions
    Replies: 82
    Last Post: - 15th December 2013, 09:54
  2. Minimizing code space
    By Tobias in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 30th May 2009, 07:25
  3. Replies: 1
    Last Post: - 23rd May 2009, 09:22
  4. Need more code space
    By ghutchison in forum General
    Replies: 1
    Last Post: - 12th February 2005, 20:54
  5. oscillator code and placement within program
    By bartman in forum mel PIC BASIC
    Replies: 14
    Last Post: - 14th December 2004, 02:39

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts