Pre-Defining EEPROM Values in XC8 Compiler

To test all below I used MPLAB 8.76, compiler XC8 ver 1.30:

First a digression/advice: If you have switched to PIC16F690 recently: ~ 6 weeks ago I decided to abandon this chip, except for really small projects. It has little FLASH, little RAM and only 256 EEPROM. And you can not debug it easily on real target. I use 18FK4620 now: it has 16 times as much FLASH (64kB) , 4 times more EEPROM (1kB), and almost 16 times RAM (~ 4kB), it can run at up to 64MHz Fosc (!), plus more ports, etc.

And the MOST IMPORTANT: you can DEBUG 18F46K20 using standard PICKIT2 and MPLAB 8.76 ... 8.91 (I do not use MPLAB X yet, as I heard a lot of bad stories about it). And you do not need any extra interface boards etc. Just your target board --> PICKIT2 (i.e. you do not have to switch to a mishap PICKIT3)

And price is very similar: 18F46K20 is ~ $2.90 and 16F690 is ~ $2.40 in retail.

NOW SOLUTIONS FOR YOU:

---------------------- Solution 1a: Use something like this (and change '20' to the array size you want):

__eeprom unsigned char my_eeprom_values[20] =  
        {   0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20,
            0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30};**

But if you use the above then you do NOT know where compiler will place these in EEPROM. (Note though that __eeprom qualifier is ignored by XC8 compiler for many PIC18Fxxx devices)

---------------------- Solution 1b:

const unsigned char abc1 @ 0x2100 = 0x11; // @ EEPROM addr = 0
    // ......
    const unsigned char abc2 @ 0x2110 = 0x22; // @ EEPROM addr = 17**

Note that it looks that EEPROM in 16F690 starts at addr. 0x2100 (not 0xF00000 as you mentioned). I checked .map file after build. I also checked the result of the above after compiling the code and then I viewed the EEPROM using PICKIT2 (or if you debug under MPLAB using MPLAB SIM, then after you build the code, go to Menu -> VIEW -> EEPROM). You will see al data there as desired.

---------------------- Solution 1c:

You can mix (1a) and (1b) above, you can use 'int' instead of 'char', but : - be aware that because __EEPROM_DATA does not allow to specify the eerpom address, one statement will overwrite some of the other ones. To illustrate this I placed 0x99 in locations that WOULD be overwritten. XC8 warns about this anyway - see the end of my post. - Endian that XC8 uses 'swaps' bytes OF 'int' type: the below 'abc' data will be stored as : 22114433, instead of as 11223344.

---------------------- EXAMPLE:

Here is a tested example for 16F690 under XC8 ver 1.30:

    const unsigned int abc1 @ 0x2100 = 0x1122;
    const unsigned int abc2 @ 0x2102 = 0x3344;
  __EEPROM_DATA(0x99, 0x99, 0x99, 0x99, 5, 6, 7, 8);
    const unsigned int abc3 @ 0x2108 = 0x5566;
    __EEPROM_DATA(0x99, 0x99, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88);
    __eeprom unsigned char my_eeprom_values[20] = \ 
    {   0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20,
        0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30};

Resulting EEPROM CONTENTS is this:

22 11 44 33 05 06 07 08 66 55 83 84 85 86 87 88
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
27 28 29 30 FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF ...

So 0x(22 11 44 33) have overwritten 4 x 0x99. Same with 0x(66 55). But note that the rest is just a plain copy of data in C code.

---------------------- Solution 2: 'yours': Just as you said place as many '8 byte' long __EEPROM_DATA statements as you need. What's wrong with this ? It is simple and works always. Compiler places data in the order you will have them in your C code. If you need some bytes to be unchanged then place 0xFF for them. Eg.

__EEPROM_DATA(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);  // addr: 0x00 ... 0x07 
__EEPROM_DATA(0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88);  // addr: 0x08 ... 0x0F
__EEPROM_DATA(0x55, 0x66, 0x87, 0x65, 0xFF, 0xFF, 0xFF, 0xFF);  // addr: 0x10 ... 0x17 
etc.

During build in (1b/1c) XC8 compiler gives these warnings:

.... object "_abc1" lies outside available code space

... (1343) hexfile data at address 0x4200 (0x99) overwritten with 0x22 

but I got data I wanted in EEPROM where I wanted it so I don;t care.

Memory Summary: Program space used F00h ( 3840) of 1000h words ( 93.8%) Data space used E4h ( 228) of 100h bytes ( 89.1%) EEPROM space used 24h ( 36) of 100h bytes ( 14.1%) ...

-end-


After looking at the above suggestions and and some other searches i came across the following solution. This includes the updates to compiler so I am using MPLABX 5.25 and XC8 v2.1. I used the following command since eeprom for the PIC1846K80 is "located" starting at 0xF00000.

const uint8_t my_variable __at(0xF0000C) = 0xA5; //0xF0000C to write at location 0xC

The above yielded the following a hex file with the following chunk. The first line indicates that it is now referring to eeprom, second line lists 1 byte at memory 0x0C of eeprom has 0xA5, last line indicates end of file.

:0200000400F00A // offset to eeprom location

:01000C00A54E // at at eeprom address 0x0C write 0xA5

:00000001FF // end of file

Tags:

Pic

Mplab

Xc8

C18