CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

[Solved]Loading eeprom with some initial values
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
haxan7



Joined: 27 Jul 2013
Posts: 79

View user's profile Send private message

[Solved]Loading eeprom with some initial values
PostPosted: Sat Sep 14, 2013 7:14 am     Reply with quote

Is there any way i can load eeprom on my pic with some initial values?
I have a program that reads eeprom at the beginning and does some calculation based on the readings. I have to mass program pics and i am looking for a way to easily load eeprom with some default values at the time of programming.


Last edited by haxan7 on Sat Sep 14, 2013 12:01 pm; edited 1 time in total
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Sat Sep 14, 2013 7:38 am     Reply with quote

the datasheet for you pic will show an address for
direct access to the EEPROM during programming.

Quote:

#ROM directive:
Another method is to use #rom to assign data to program memory.
The syntax is:
#rom address = {data, data, … , data}
For example:
Places 1,2,3,4


the eeprom address is located far above the normal end of prog mem space
Ttelmah



Joined: 11 Mar 2010
Posts: 19447

View user's profile Send private message

PostPosted: Sat Sep 14, 2013 11:49 am     Reply with quote

And the _programming_ data sheet, tells you where to put the data.

Best Wishes
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Sat Sep 14, 2013 7:33 pm     Reply with quote

Hi,

I like to do it like this:

Code:

#ROM int8 getenv("EEPROM_ADDRESS") = {0, 0, 9, 7, 8, 24, 24}


If you do it like this, the compiler figures out the address of the EEPROM, making the code much more portable from PIC to PIC.

John
bela



Joined: 31 Aug 2008
Posts: 27
Location: Bedford, BEDS UK

View user's profile Send private message Visit poster's website

PostPosted: Sun Sep 15, 2013 12:25 pm     Reply with quote

Hi,

You can also do it from MPLAB 8.x (don't know about MPLABX)

View->eeprom poke the values in and you can save it to a file.

When you program, the table will burn to the eeprom provided that you have the eeprom memory region switched on in programmer->settings.

Main advantage over hard coding is if the data is variable. e.g serial number.

Darren.
_________________
There are 10 types of people in this world; those who understand binary and those who don't.
webgiorgio



Joined: 02 Oct 2009
Posts: 123
Location: Denmark

View user's profile Send private message

How to initialize eeprom values when flashing the chip?
PostPosted: Sat May 31, 2014 12:46 pm     Reply with quote

What's wrong in this test program?
The intent is to initialize the EEPROM locations 0, 1, 2 with the values 101, 102, 103.
However uncommenting #ROM it does not compile.

Code:
/*****************************************************
 test the initialization of a EEPROM location
*******************************************************/

#include <16F886.h>
#fuses INTRC_IO, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(clock=8M, restart_wdt)
#use rs232(baud=19200,xmit=PIN_C6,rcv=PIN_C7)

#define buzer PIN_C4

//#ROM 0 = {100,101,102}
//#ROM 1 = {101}
//#rom 2 = {102}

int1  flag1;

#int_TIMER1 //----------------------------------------------------------------
void TIMER1_isr(void){ // 4Hz interrupt
   //set_timer1(0x0BDC); //3036 in hex is 0BDC
   flag1=1;
}

//----------------------------------------------------------------------------
void main() {
   SETUP_SPI(SPI_SS_DISABLED);
   setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8 ); //gives around 4 Hz interrupt
   enable_interrupts(int_TIMER1);
   enable_interrupts(global);
   printf("\n\n***** booting... ******\n\n");
   printf("add: %u\n",getenv("EEPROM_ADDRESS"));
   printf("eeprom data0= %u\n", read_eeprom(0));
   printf("eeprom data1= %u\n", read_eeprom(1));
   while(1){
      if (flag1) {
         output_toggle(buzer);
         flag1=0;
      }
   }
} //end main


The datasheet says "These devices have 256 bytes of data EEPROM with an address range from 0h to 0FFh."
dyeatman



Joined: 06 Sep 2003
Posts: 1931
Location: Norman, OK

View user's profile Send private message

PostPosted: Sat May 31, 2014 12:54 pm     Reply with quote

Why did you totally ignore what ezflyer showed you?
Code:
#ROM int8 getenv("EEPROM_ADDRESS") = {0, 0, 9, 7, 8, 24, 24}


Just change the values in his example!
_________________
Google and Forum Search are some of your best tools!!!!
webgiorgio



Joined: 02 Oct 2009
Posts: 123
Location: Denmark

View user's profile Send private message

PostPosted: Sat May 31, 2014 4:06 pm     Reply with quote

Of course I tried, I get exactly the same error as with
Code:
#ROM int8 0 = {100,101,102}

I know that the first eeprom location is 0 from datasheet and because I print it in the code using getenv("EEPROM_ADDRESS");.

Error 126: invalid ORG range.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat May 31, 2014 4:29 pm     Reply with quote

Quote:
I know that the first eeprom location is 0 from datasheet

Download the Programming Specifcation for the 16F886:
http://ww1.microchip.com/downloads/en/DeviceDoc/41287D.pdf

Read this section:
Quote:
5.3.2 EMBEDDING DATA MEMORY CONTENTS IN HEX FILE

What address does it say should be used with org ?
dyeatman



Joined: 06 Sep 2003
Posts: 1931
Location: Norman, OK

View user's profile Send private message

PostPosted: Sat May 31, 2014 4:46 pm     Reply with quote

The line I showed compiles in your code with no problem. I don't
understand why you are having issues.

Code:
/*****************************************************
 test the initialization of a EEPROM location
*******************************************************/

#include <16F886.h>
#fuses INTRC_IO, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(clock=8M, restart_wdt)
#use rs232(baud=19200,xmit=PIN_C6,rcv=PIN_C7)

#define buzer PIN_C4

#ROM int8 getenv("EEPROM_ADDRESS") = {101,102, 103, 104, 105, 106, 107}

int1  flag1;

#int_TIMER1 //----------------------------------------------------------------
void TIMER1_isr(void){ // 4Hz interrupt
   //set_timer1(0x0BDC); //3036 in hex is 0BDC
   flag1=1;
}


The .LST file below shows the data exactly where it should be.
What version of the compiler are you using?

Quote:
Configuration Fuses:
Word 1: 2FE4 INTRC_IO NOWDT PUT MCLR NOPROTECT NOCPD BROWNOUT IESO FCMEN NOLVP NODEBUG
Word 2: 3FFF BORV40 NOWRT

ROM data:
002100: 0065 0066 0067 0068 0069 006A 006B

_________________
Google and Forum Search are some of your best tools!!!!
Ttelmah



Joined: 11 Mar 2010
Posts: 19447

View user's profile Send private message

PostPosted: Sun Jun 01, 2014 12:25 am     Reply with quote

and the answers in the original thread also give it all.

My first line:
"And the _programming_ data sheet, tells you where to put the data."
PCM_programmer has repeated this point. Note 'programming', not the main data sheet.

As ezflyr points out, on newer compilers, the 'getenv' solution is better, but was still a bit borderline at the date of the original post. This only works with reasonably modern compilers.

The key is to understand that #ROM, uses addresses as a device programmer uses them. So 'address 0', is the first address in the program itself, not the EEPROM.

I'd suspect perhaps he is printing the getenv, as an int, which will then return '0' (since the low byte of 0x2100, is 00), and is then for some inane reason hard-coding 0, rather than realising the mistake, and using 0x2100, or the real value returned by getenv....
webgiorgio



Joined: 02 Oct 2009
Posts: 123
Location: Denmark

View user's profile Send private message

PostPosted: Sun Jun 01, 2014 1:54 am     Reply with quote

getenv("EEPROM_ADDRESS") always gives me 0x00 :/ so I will just use the direct address from the _programming_ datasheet as suggested by Ttelmah. (I apologize, I totally ignored the existence of a different data sheet for programming).
My compiler is old, less than v4, it is probably the reason why getenv() does not work, and also I had to remove the "int8" after "#ROM" in order for the program to work.
So now it works, and here is the test code.
But what if I want to save an int16?
I am wandering of just use #ROM on the first eeprom location to see if it is the first time that the chip is booted, and then load all the int16 constants in rest of the eeprom with to_eeprom(address, val) (http://www.ccsinfo.com/forum/viewtopic.php?t=52454).
Is in it any drawback? (besides a bit of program memory use).

Code:

/*****************************************************
 test the initialization of a EEPROM location
*******************************************************/
#include <16F886.h>
#fuses INTRC_IO, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(clock=8M, restart_wdt)
#use rs232(baud=19200,xmit=PIN_C6,rcv=PIN_C7)
//#ROM int8 getenv("EEPROM_ADDRESS") = {0, 0, 9, 7, 8, 24, 24}
#ROM 0x2100 = {100,101}
#ROM 0x2102 = {102}
void main() {
   printf("\n\n***** booting... ******\n\n");
   printf("eeprom data0= %u\n", read_eeprom(0));
   printf("eeprom data1= %u\n", read_eeprom(1));
   printf("eeprom data2= %u\n", read_eeprom(2));
   while(1){
   }
}

Quote:
***** booting... ******

eeprom data0= 100
eeprom data1= 101
eeprom data2= 102
Ttelmah



Joined: 11 Mar 2010
Posts: 19447

View user's profile Send private message

PostPosted: Sun Jun 01, 2014 2:58 am     Reply with quote

I repeat are you sure that getenv is returning 0?. I suspect you are looking the int8 value from it, which will be 0....
The alternative is that you have a massively old compiler, or a damaged chip database.

There is no point in 'just use #ROM on the first eeprom location to see if it is the first time that the chip is booted'. Unprogrammed EEPROM locations return 255 (it is in the data sheets).
Either load the chip with the data required, or leave it unprogrammed and just load it if the EEPROM is blank.
webgiorgio



Joined: 02 Oct 2009
Posts: 123
Location: Denmark

View user's profile Send private message

PostPosted: Sun Jun 01, 2014 5:14 am     Reply with quote

How should I display it? With this I get "add: 00".
Code:
printf("add: %Lx\n",getenv("EEPROM_ADDRESS"));


True there is no point, I could simply check if it is 255. Something like this: (I haven't tried to run it)
Code:

#define rom_A 0
#define rom_B 2
#define rom_C 4

main(){
 int16 A,B,C;
 A=1200; B=300; C=100;
 if(read_eeprom(0)==255){
   to_eeprom(rom_A, A)
   to_eeprom(rom_B, B)
   to_eeprom(rom_C, C)
 }
 while(1){ }
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19447

View user's profile Send private message

PostPosted: Sun Jun 01, 2014 2:39 pm     Reply with quote

Of course it would.....

You can't use getenv like that. Getenv, is a compile time effectively 'macro' substitution, which puts the specified number or string 'into' that location in the code. Printf, requires a variable or function return value. You have to use:
Code:

   int32 addr;
   addr=getenv("EEPROM_ADDRESS");
   printf("%Ld\n",addr);

To print the value that getenv generates.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group