|
|
View previous topic :: View next topic |
Author |
Message |
haxan7
Joined: 27 Jul 2013 Posts: 79
|
[Solved]Loading eeprom with some initial values |
Posted: Sat Sep 14, 2013 7:14 am |
|
|
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
|
|
Posted: Sat Sep 14, 2013 7:38 am |
|
|
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: 19561
|
|
Posted: Sat Sep 14, 2013 11:49 am |
|
|
And the _programming_ data sheet, tells you where to put the data.
Best Wishes |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Sat Sep 14, 2013 7:33 pm |
|
|
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
|
|
Posted: Sun Sep 15, 2013 12:25 pm |
|
|
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
|
How to initialize eeprom values when flashing the chip? |
Posted: Sat May 31, 2014 12:46 pm |
|
|
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: 1938 Location: Norman, OK
|
|
Posted: Sat May 31, 2014 12:54 pm |
|
|
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
|
|
Posted: Sat May 31, 2014 4:06 pm |
|
|
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
|
|
Posted: Sat May 31, 2014 4:29 pm |
|
|
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: 1938 Location: Norman, OK
|
|
Posted: Sat May 31, 2014 4:46 pm |
|
|
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: 19561
|
|
Posted: Sun Jun 01, 2014 12:25 am |
|
|
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
|
|
Posted: Sun Jun 01, 2014 1:54 am |
|
|
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: 19561
|
|
Posted: Sun Jun 01, 2014 2:58 am |
|
|
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
|
|
Posted: Sun Jun 01, 2014 5:14 am |
|
|
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: 19561
|
|
Posted: Sun Jun 01, 2014 2:39 pm |
|
|
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 |
|
|
|
|
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
|