|
|
View previous topic :: View next topic |
Author |
Message |
alexandre
Joined: 10 Dec 2010 Posts: 7
|
PIC18F87J11 Read and Write on DATA memory |
Posted: Fri Dec 10, 2010 4:33 am |
|
|
Hello every body,
I just started programming PIC18F, I'm using CCS 4.049
The built-in read_eeprom() and write_eeprom() functions are not recognised when I compile my program.
The error message is:
"*** Error 12 "main.c" Line 74(16,17): Undefined identifier -- write_eeprom"
some one would help me please.
I want to save some information in the data memory of the PIC18F87J11. According to its datasheet this PIC has 3930 Bytes of data memory.
Does there any way (other than read_eeprom() and write_eeprom() built-in functions) to manage the Data Memory of PIC18F87J11?
Thank you very much for your help |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19505
|
|
Posted: Fri Dec 10, 2010 5:03 am |
|
|
'Data memory', is not the EEPROM.
PIC's have three types of memory. The 'program' memory (Flash), the 'data' memory (RAM), and (in some cases) EEPROM.
Each is used for slightly different things, and is addressed separately. So the RAM, occupies a separate 'memory space' to the flash (often also called ROM, since on early chips, this memory was 'read only' - you could not reprogram these from code) - this layout is distinct from processors like the PC 80xx family, which have a 'unified' address space.
Your chip doesn't have any EEPROM.
The 'data memory', is the RAM memory, where all your variables are going.
You can store values in the flash ROM. Multiple ways:
1) If you declare a 'const', it is automatically stored in the ROM for you.
2) If you declare a 'rom' variable, it too is automatically stored in the ROM for you, but is handled sligtly differently, allowing pointers to be constructed to such a value (I won't call them 'variables', since unlike values in data memory, which can 'vary', these are constant, and require the section of memory to be reprogrammed to change them.
3) You can also use a #ROM statement, to define a block of data to be stored in the ROM.
For cases 2, and 3, you can then read and write these areas (with caveats), using the read_program memory, write_program_memory, and write_program_eeprom functions.
First big caveat. Unlike the EEPROM, which allows single bytes to be erased, the program memory only allows 'blocks' to be erased. You _must_ erase an area, before writing to it, if you want the data you write to be stored correctly. So you really have to read the entire block, change just the bytes you want, erase the block, and then write the block back. The write_program_memory function, will _automatically_ erase the whole block, if you write to the first address using this.
On your chip, I think the block size if large (512words)....
The second caveat, is 'life'. The flash memory, has only a limited number of 'write cycles' that can be done. Whereas EEPROM, typically has a like of perhaps 100K to 1M cycles, the main program memory has a much lower life figure often of only perhaps 100 cycles. Writing to this very often, is then a sure way to kill your chip....
A number of choices:
1) For something that needs only change very occasionally (reprogrammed every few months), writing to the flash, may be acceptable.
2) Change to a chip that has some EEPROM.
3) Add an external I2C EEPROM or (better for fast writing), and FRAM.
Best Wishes |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Fri Dec 10, 2010 10:08 am |
|
|
On the 46j11 (as an example from the same family),
The flash cell ENDURANCE (typically is the buzzword you want to find the spec for) is listed at a minimum of 10,000 Erase/Write cycles.
And as TTelmah says: It's not meant to be used like RAM. It's life is finite. Therefore, a write every second would only be guaranteed to burn out the cell in at least 10,000 seconds (an hour is 3600 seconds, a day is 86,400 seconds).
Writing to FLASH (like writing to EEPROM) is typically meant for storing seldom saved configs.
Cheers,
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
alexandre
Joined: 10 Dec 2010 Posts: 7
|
|
Posted: Fri Dec 10, 2010 11:25 am |
|
|
Oh thank you for your rapid replys,
Let me explain you my application, In fact I want to store a measurement every day, it is the same measure, it will be updated then stored every day in the same memory location.
If for some reason my PIC shutdown, I want to retrieve the last value recorded in memory.
Thank you Ttelmah for your propositions. I will try to add an external EEPROM. I think I have somewhere an EEPROM 24LC256 with I2C interface.
But before adding this to my platform, would you please tell me why the :
#use i2c() don't work with HW option (with SW option it is ok), (code for PIC18F87J11 using CCS version 4.049).
I have an I2C sample for driving the DS1307 (RTC from Maxim), if you would like to see this code, I will post it later.
Thank you |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Fri Dec 10, 2010 11:27 am |
|
|
There's 56bytes of NV ram in the DS1307... (as long as the battery is good while the power is off)
Why not use that?
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
gpsmikey
Joined: 16 Nov 2010 Posts: 588 Location: Kirkland, WA
|
|
Posted: Fri Dec 10, 2010 12:42 pm |
|
|
If I remember correctly (although at my age, that may be questioned ... ), the DS1307 was the chip used in some of the early PC's for both the RTC as well as storing the BIOS config info so that is definitely an option if you have that in your system (the little coin cell CR2032 makes a good battery for that application and is available almost everywhere. about 180mah).
If you are using a RTC like the DS1307, another one you might want to consider (it is cheaper) is the MCP79410 from Microchip. Here is a link to that one and an application for it:
http://ww1.microchip.com/downloads/en/AppNotes/01355A.pdf
http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en550280
It has 64bytes of SRAM (battery backed up) as well as 1k bits (not bytes) of eeprom. I bought some recently, but have not had a chance to use them yet.
mikey _________________ mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3
Last edited by gpsmikey on Fri Dec 10, 2010 12:48 pm; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
alexandre
Joined: 10 Dec 2010 Posts: 7
|
|
Posted: Fri Dec 10, 2010 1:44 pm |
|
|
a good idea, thank you bkamen,
I would like at first implement a Software solution (RTC + storage + some other tasks), then I will make a complete Hardware solution (DS1307, EEPROM, ...)
|
|
|
alexandre
Joined: 10 Dec 2010 Posts: 7
|
|
Posted: Fri Dec 10, 2010 2:07 pm |
|
|
Thank you everybody for your advice,
But I still have a question about the problem of #use i2c() with HW option for the PIC18F87J11. It works when SW option is specified.
Any idea ....
Alex |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Fri Dec 10, 2010 4:48 pm |
|
|
You should probably specify which I2C unit...
try:
Code: | #use i2c (i2c1, stream=MY_I2C_STREAM, FORCE_HW) |
This will force using hardware MSSP1 in I2C mode. It's a guess... you might want to add FAST or SLOW options for speed control.
You don't show us the actual line in your code (which might help)...
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
alexandre
Joined: 10 Dec 2010 Posts: 7
|
|
Posted: Fri Dec 10, 2010 5:12 pm |
|
|
Well, this is my declaration :
Code: |
//RTC - DS1307 I2C Stream
#define DS1307_SDA PIN_D5
#define DS1307_SCL PIN_D6
#use i2c(master, sda = DS1307_SDA, scl = DS1307_SCL, stream = RTC_STREAM, FORCE_SW, FAST = 100000)
//EEPROM - 24LC256 I2C Stream
#define EEPROM_24LC256_SDA PIN_C4
#define EEPROM_24LC256_SCL PIN_C3
#use i2c(master, sda = EEPROM_24LC256_SDA, scl = EEPROM_24LC256_SCL, stream = EEPROM_STREAM, FORCE_SW, FAST = 100000) |
When FORCE_SW is used I2C communication between my PIC18F87J11 and RTC is established.
If I change it to FORCE_HW, there is no I2C communication, my PIC execute:
Code: | Data = i2c_read(RTC_STREAM,0); |
and loop forever (I think a problem of ACK, but not sure)
Thanks bkamen |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Fri Dec 10, 2010 5:34 pm |
|
|
Well, for one, the I2C fast specification is for 400KHz operation, not 100KHz. That's actually the SLOW specification.
Anyway -- you have 2 I2C setups.
You NEED to add which I2C module needs to go to both.
//RTC - DS1307 I2C Stream
#define DS1307_SDA PIN_D5
#define DS1307_SCL PIN_D6
#use i2c(I2C2, master, sda = DS1307_SDA, scl = DS1307_SCL, stream = RTC_STREAM, FORCE_SW, FAST = 100000)
//EEPROM - 24LC256 I2C Stream
#define EEPROM_24LC256_SDA PIN_C4
#define EEPROM_24LC256_SCL PIN_C3
#use i2c(I2C1, master, sda = EEPROM_24LC256_SDA, scl = EEPROM_24LC256_SCL, stream = EEPROM_STREAM, FORCE_SW, FAST = 100000)
BTW, you DO realize you can put BOTH I2C slaves on the same bus provided their 7bit addy's are different, right?
But anyway - try that. _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
alexandre
Joined: 10 Dec 2010 Posts: 7
|
|
Posted: Fri Dec 10, 2010 5:56 pm |
|
|
Ok I will try this:
Code: |
//EEPROM - 24LC256 I2C Stream
#define EEPROM_24LC256_SDA PIN_C4
#define EEPROM_24LC256_SCL PIN_C3
#use i2c(I2C1, master, sda = EEPROM_24LC256_SDA, scl = EEPROM_24LC256_SCL, stream = EEPROM_STREAM, FORCE_HW, SLOW = 100000)
//RTC - DS1307 I2C Stream
#define DS1307_SDA PIN_D5
#define DS1307_SCL PIN_D6
#use i2c(I2C2, master, sda = DS1307_SDA, scl = DS1307_SCL, stream = RTC_STREAM, FORCE_HW, SLOW = 100000)
|
|
|
|
|
|
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
|