[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-Demon");
    ee_read_byte(0x00, &from_eeprom);
    printf("Char read from 0x00: %cn", from_eeprom);
    
    ee_write_byte(0x00, &save_me);
    printf("Char written to 0x00: %cn", save_me);
    
    ee_read_byte(0x00, &from_eeprom);
    printf("Char read from 0x00: %cnn", from_eeprom);
}
Previous Post
Leave a comment

32 Comments

  1. anonymous

     /  July 12, 2006

    Anonymous writes:hi;I try to compile your example code but the output was:mramirez@floyd:~/picCode$ sdcc -mpic16 main.clibio18f452.lib: No such file or directoryand 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 isSDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.5.0 #1020 (Mar 18 2006) (UNIX)my pic model is: pic18lf4620

    Reply
  2. raphman

     /  July 20, 2006

    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.cThe -m architectures are named very confusingly: pic14 means 16Fxxxx PICs and pic16 means 18Fxxxx PICs. There is no -mpic18I'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

    Reply
  3. anonymous

     /  December 14, 2007

    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

    Reply
  4. raphman

     /  December 18, 2007

    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, thatis used for long-term storage of program data. It is notdirectly mapped in either the register file or programmemory space, but is indirectly addressed through theSpecial Function Registers (SFRs)."If this didn't answer your question, please ask again.

    Reply
  5. anonymous

     /  June 3, 2008

    strum writes:

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

    Reply
  6. raphman

     /  June 3, 2008

    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.

    Reply
  7. anonymous

     /  June 3, 2008

    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.

    Reply
  8. anonymous

     /  June 23, 2008

    arkadi writes:

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

    Reply
  9. anonymous

     /  June 23, 2008

    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 :10420000AA001E00000001000A0064001E00010058SDCC :10420000AA341E34003401340A3464341E340134B8

    Reply
  10. raphman

     /  June 24, 2008

    @arkadi: Thanks!

    Reply
  11. anonymous

     /  November 4, 2008

    fermintol writes:

    10 // '10' = 115200 Baud with 20 MHz oscillator and BRGH=1how I calculate this parameter? I try to search any documentation, but i don't found😦.

    Reply
  12. anonymous

     /  November 11, 2008

    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

    Reply
  13. anonymous

     /  November 11, 2008

    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

    Reply
  14. raphman

     /  November 13, 2008

    Thanks, vaclavpe!

    Reply
  15. urefowei

     /  January 7, 2009

    ohh. by the way..our project is about transferring data from a USB storage device to another USB storage device.. thankspls contact me please..

    Reply
  16. urefowei

     /  January 7, 2009

    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.comor by gmail at, urefowei@gmail.comwe really think you are of big help to us!!thank you!

    Reply
  17. raphman

     /  January 8, 2009

    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 FrameworkIf you put code from your project online, please let me know.

    Reply
  18. urefowei

     /  January 8, 2009

    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!

    Reply
  19. anonymous

     /  June 26, 2009

    Mr-M writes:Ur Code Was So HelpfulThanks a lot……………………………………………………

    Reply
  20. anonymous

     /  November 11, 2009

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

    Reply
  21. anonymous

     /  January 23, 2010

    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!

    Reply
  22. anonymous

     /  April 11, 2010

    lizzy writes:hello,can i have d code in c that store temperature data to EEPROM? please do help me

    Reply
  23. anonymous

     /  May 26, 2010

    Anonymous writes:Hi am using Hi-Tech C Pro and PIC18F4550 can anyone help me read a/d channel. any sample code will be very helpful.

    Reply
  24. anonymous

     /  August 5, 2010

    SB writes:I am looking to program a 18F46xxx using SDCC compiler. My requirement is to drive a LCD,a usart,may be a SPI also. I have been using MPLAB IDE previously(for dsPIC and 16F PIC). I would like to know whether SDCC can used with MPLAB IDE ? if yes, can u pls tell the procedure(or say some url stuff). Thanks in Advance🙂

    Reply
  25. anonymous

     /  October 17, 2010

    iain maoileoin writes:Nice bit of codethanks.Much better than the "must be in assember" sort of stuffworks a treat on my 4520Any other samples?

    Reply
  26. anonymous

     /  February 9, 2011

    Anonymný writes:hello, please advice, I want to program the PIC18F458, I dump, I assembled a programmer with external power supply, pčítač with COM port, it looks that the communication is fine, but prints an error adrress verify failed at 0000h. What can it be? Thank you, Regards Baloo

    Reply
  27. raphman

     /  February 9, 2011

    Hi Baloo,that's hard to say from this description. Does your programmer pull down _MCLR when programming, as it should? Do you have a schematic of your programmer?

    Reply
  28. anonymous

     /  February 9, 2011

    Anonymný writes:My programmer:http://www.bobtech.ro/catalog/programator/index.htmlPower MCLR is 13.2 V, others actually do not know how I work, I have experience with it, I used ICPROG106B. I do not know if it helps, I tried to measure the outputs: PGD —— gnd:data on ……. 5.2V —– off …….. 0VPGC …… gnd:clock on …… 5.6v —- off …….. 0V VCC on ……. 0V off ……… 5.6v MCLR ………. 13.3V is that okay?Thanks, Baloo

    Reply
  29. raphman

     /  February 9, 2011

    I think you should ask on PIClist ( http://www.piclist.com/techref/piclist/index.htm ) – there are a number of people who know much more than me about PIC programmers.

    Reply
  30. anonymous

     /  July 20, 2011

    Lonely Coder writes:Great, thank you.

    Reply
  31. anonymous

     /  August 11, 2011

    Анонімний writes:When you're in not good state and have got no money to move out from that point, you will have to receive the loan. Because it will aid you for sure. I get credit loan every time I need and feel good because of this.

    Reply
  32. anonymous

     /  December 2, 2011

    Dave Bronke writes:I recently picked up a PIC18 for the first time in 5 years, and was searching around for a simple example program for SDCC on the PIC18 series, and yours was the first I've come across that actually had a full, useful example.I'm putting together a custom USB-based controller for a Kinesis contoured keyboard. The EEPROM code itself will come in handy when I get to the point of storing keymaps on the PIC, but the general structure has already proven quite useful for my project.Thanks for posting this!

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: