Skip navigation.

Raphael's Pflock

miscellaneous Opera, Debian, Media and German posts

[SDCC] Accessing EEPROM on PIC18 - simple example

Neither optimized (you could/should use inline assembler) nor most user-friendly (only writes single chars). However, sample code for sdcc is scarce :-)

// read and write eeprom of PIC18F2550 (and 18F2455, 18F4455, 18F4550)
// EEPROM size is 256 bytes
// (c) Raphael Wimmer. Licensed under GNU GPL v2 or higher

#include <pic18fregs.h>
#include <stdio.h>
#include <usart.h>

#pragma stack 0x300 0xff // set 64 byte stack at 0x300, needed by sdcc


void ee_write_byte(unsigned char address, unsigned char *_data){

    EEDATA = *_data;
    EEADR = address;
    // start write sequence as described in datasheet, page 91
    EECON1bits.EEPGD = 0;
    EECON1bits.CFGS = 0;
    EECON1bits.WREN = 1; // enable writes to data EEPROM
    INTCONbits.GIE = 0;  // disable interrupts
    EECON2 = 0x55;
    EECON2 = 0x0AA;
    EECON1bits.WR = 1;   // start writing
    while(EECON1bits.WR){
        _asm nop _endasm;}
    if(EECON1bits.WRERR){
        printf("ERROR: writing to EEPROM failed!\n");
    }
    EECON1bits.WREN = 0;
    INTCONbits.GIE = 1;  // enable interrupts
}

void ee_read_byte(unsigned char address, unsigned char *_data){
    EEADR = address;
    EECON1bits.CFGS = 0;
    EECON1bits.EEPGD = 0;
    EECON1bits.RD = 1;
    *_data = EEDATA;
}

void initUsart()
{
    usart_open(    // Use USART library to initialise the hardware
            USART_TX_INT_OFF
            & USART_RX_INT_OFF
            & USART_BRGH_HIGH
            & USART_ASYNCH_MODE
            & USART_EIGHT_BIT,
            10                      // '10' = 115200 Baud with 20 MHz oscillator and BRGH=1
            );
    stdout = STREAM_USART;
}



// very simple example. use on an erased eeprom

void main(){
    char save_me = 'x';
    char from_eeprom;

    initUsart();
    
    printf("EEPROM-Demo\n");
    ee_read_byte(0x00, &from_eeprom);
    printf("Char read from 0x00: %c\n", from_eeprom);
    
    ee_write_byte(0x00, &save_me);
    printf("Char written to 0x00: %c\n", save_me);
    
    ee_read_byte(0x00, &from_eeprom);
    printf("Char read from 0x00: %c\n\n", from_eeprom);
}

farewell netscapeserial-to-tcp-socket bridge

Comments

Anonymous 12. July 2006, 17:55

Anonymous writes:

hi;

I try to compile your example code but the output was:

mramirez@floyd:~/picCode$ sdcc -mpic16 main.c
libio18f452.lib: No such file or directory

and this..

mramirez@floyd:~/picCode$ sdcc -mpic18 main.c
-:0: error 131: cannot generate code for target 'pic18'

i'm a new sdcc user, can you help me?
------------------
my sdcc version is
SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.5.0 #1020 (Mar 18 2006) (UNIX)

my pic model is: pic18lf4620

Raphael Wimmer 20. July 2006, 20:55

Sorry for the late response.
I'm not quite sure if your PIC is supported by sdcc. The (not current) snapshot of sdcc I use doesn't include header files for the 18f4620 or other PICs from its family.

Usually you have to provide both architecture and model of the microcontroller to sdcc.

If your PIC is supported the following command should work:
sdcc -mpic16 -p18f4620 main.c

The -m architectures are named very confusingly: pic14 means 16Fxxxx PICs and pic16 means 18Fxxxx PICs. There is no -mpic18

I'll post some more (easier to use) example code on this blog the next days. However, I still doubt that your PIC model is supported by sdcc. If it is not, one could write appropriate header and linker files - but this involves lots of reading in the datasheet and a better understanding of the PIC architecture and gplink/sdcc than I (and perhaps you) have.

Raphael

Anonymous 14. December 2007, 21:02

Tercio Ferdinando Gaudencio Filho writes:

Hy Raphael!

Do you know how to add EEPROM code to compiled code(HEX)?

Like:
code unsigned short at 0x03F00 _VARIABLE = 0x0C;

This insert a 0x0C into 0x03F00 address of Flash memory. Do you know how to do it for EEPROM?

Regards,

Tercio

Raphael Wimmer 18. December 2007, 07:04

Hi Tercio,
I'm not sure if I completely understand your question.
In your example you can access _VARIABLE because it is memory-mapped. However, on the 18F2550,18F2455,18F4550,18F4455 the EEPROM is not mapped to main memory. See datasheet:

"The data EEPROM is a nonvolatile memory array,
separate from the data RAM and program memory, that
is used for long-term storage of program data. It is not
directly mapped in either the register file or program
memory space, but is indirectly addressed through the
Special Function Registers (SFRs)."

If this didn't answer your question, please ask again.

Anonymous 3. June 2008, 18:29

strum writes:

hi.. is this allow me to perform data storage and display in USART?

Raphael Wimmer 3. June 2008, 19:44

Hi strum,
I do not completely understand your question. The EEPROM code does not depend on the USART code. I just initialized USART for printing out status messages over the serial line. Of course you could send data to be stored in the EEPROM via the serial connection. However, 256 Bytes are not that much.

Anonymous 3. June 2008, 20:33

strum writes:

sorry i m a newbie in this. it was to like store ADC result displayed in USART in an array then show wherever you trigger it. Wasn't really clear on how to perform it.

Anonymous 23. June 2008, 10:46

arkadi writes:

There should be similar way in SDCC to predefine the EEPROM content:
http://microchip.htsoft.com/support/faqs.php#faq69

Anonymous 23. June 2008, 19:40

arkadi writes:

To predefine EEPROM SDCC way:
typedef unsigned char eeprom;
__code eeprom __at 0x2100 __EEPROM[] = { 0xAA, 0x1E, 0x00, 0x01, 0x0A, 0x64, 0x1E, 0x01 };

This is an equivalent of HI-TECH PICC:
__EEPROM_DATA(170, 30, 0, 1, 10, 100, 30, 1);

In hex file there is a RETLW opcode (0x34) instead of 00, but according to GPSIM it doesn't matter:
PICC :10420000AA001E00000001000A0064001E00010058
SDCC :10420000AA341E34003401340A3464341E340134B8

Raphael Wimmer 24. June 2008, 07:19

@arkadi: Thanks!

Anonymous 4. November 2008, 10:31

fermintol writes:

10 // '10' = 115200 Baud with 20 MHz oscillator and BRGH=1

how I calculate this parameter? I try to search any documentation, but i don't found :(.

Anonymous 11. November 2008, 12:40

Vitor writes:

Hi

I am trying to configure a serial port of pic18F. Someone have a code to read and write in this serial port to SDCC compiler?

Thanks

Anonymous 11. November 2008, 22:44

vaclavpe writes:

Sorry for comments, but Arkadi's code is correct for PIC16Fxxx but not for PIC18Fxxxx.

For PIC18F and SDCC works following:
__code char __at( 0xF00000 ) EEP_SOMEDATA[] = { 0x01, 0x20, 0x33, 0x22 };

VP

Raphael Wimmer 13. November 2008, 09:48

Thanks, vaclavpe!

Eljun Pacomios 7. January 2009, 18:32

hello raph..
i am doing a project on PIC18F4550..
i would like to ask assistance on programming this PIC's USB module.
i hope i get a reply on you from this..
you can also contact me through yahoo messenger or email at urefowei@yahoo.com
or by gmail at, urefowei@gmail.com

we really think you are of big help to us!!
thank you!

Eljun Pacomios 7. January 2009, 18:34

ohh. by the way..
our project is about transferring data from a USB storage device to another USB storage device.. thanks

pls contact me please..

Raphael Wimmer 8. January 2009, 11:52

Hi Eljun,

unfortunately I do not have that much experience with USB to be helpful. Additionally I'm extremely busy at the moment.
You might want to have a look at the PIC USB Framework

If you put code from your project online, please let me know.

Eljun Pacomios 8. January 2009, 13:09

ok.. right! no problem, we will..

thank you anyway.. but if you do know good resources about programming PIC18f4550,please feel free to let us know.. actually, we are just novice on these.. LOL.. Thanks!

Anonymous 26. June 2009, 14:44

Mr-M writes:

Ur Code Was So Helpful
Thanks a lot
............................................................

Anonymous 11. November 2009, 12:45

Anonymous writes:

Is it possible to post a working code to access an external eeprom using pic18F and C18 compiler

Anonymous 23. January 2010, 19:19

ADi writes:

Hi,
Thank you for sharing this piece of code. I used for PIC18F25K20 and compiler HI-TECH C PRO for the PIC18 MCU Family V9.63PL1 because the eeprom utility function provided by the HTSOFT doesn't work. The only modification was at the asm nop instruction, all the the code was replaced with NOP() instruction.
You did a good job!

How to use Quote function:

  1. Select some text
  2. Click on the Quote link

Write a comment

Comment
(BBcode and HTML is turned off for anonymous user comments.)

If you can't read the words, press the small reload icon.


Smilies