|
|
View previous topic :: View next topic |
Author |
Message |
antosci
Joined: 29 Apr 2013 Posts: 13
|
Write_program_memory(...) on a PIC18F47J53 issues |
Posted: Mon Apr 29, 2013 7:51 am |
|
|
Good evening everybody. i'm working on a project with pic 18f47j53 and i need to save data, coming from an input, to program memory.
During the code i already use read_program_memory(...) without problems.
i use it to read data previously stored in program memory with the command #ROM 0x7530 = {..string...}
but when i catch data from the input, and i've got it in a RAM variable, i would save it in the program memory in order to save it permanently and avoid information losing after switch off.
But my write program memory doesn't work.
i need to save a 32byte called SSID, 32 byte called key, 3 x 4byte called IP, GW, Subnet. and two more byte indicating program successfull with 0xFF and another information.
total of 78 byte.
how could i save it in the flash program memory ? how should i use write program memory for this device !?
Thank's a lot for reading |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19545
|
|
Posted: Mon Apr 29, 2013 9:34 am |
|
|
How often is it going to need to update?.
Writing to the program memory is quite 'long winded'. Problem is that you can only erase in whole pages. A page on this chip is 1024 bytes.
So if you don't need to update very often, and have the space, you could allocate (for example) the whole 'page' at 1FF800 to 1FFBFF to your data. Then generate the array you want, and write this to 1FF800 using the write_program_memory function.
This should then work. This function will automatically erase a whole page if you write to the first address in a page. Since 1FF800 is the start of a page, the function will automatically do everything.
Now, 'why 1FF800'. Reason is this is the last page in the memory you can use without extra complexity. The next page at 1FFC00, contains the configuration information. If you erase this, and then power fails before the write completes, you have a non working chip....
Downside is obviously, using a whole 1K page, and the life of the program memory is only warranted at 10000 cycles.
So what else can be done?.
There is a more complex way to emulate the EEPROM, but a lot more work. What you do it use one (or more) pages to emulate an EEPROM, and store into the 16bits of each cell, the value you want to store, and a number. The number is allowed to have values from 1 to 254, to give an 'address', with the two values '0' and '255' being used for 'empty', and 'out of use'. Then you have a program that when asked to store a value to an eeprom address of '1', searches for the first 'empty' cell, and stores '1' and the value required into this. Retrieving a value becomes a matter of looking through the words till one with the required address is found. When you want to change a value, the existing record for this address is changed to 'out of use', and a new record is written to the next 'empty' location. When the search gets to the end of the page, without finding an empty location, all currently recorded values are copied out, and either written to a second page, or the single page is erased and the values written back (without all the 'out of use' entries that corresponded to previously erased values).
Advantage here is that you only erase a page, when it fills. So in your case (with 78 bytes in use), you could write this six times before the page has to erase, and more if most of the values remain unchanged. It is though a lot more work, and slower for reading/writing the data.
Best Wishes |
|
|
antosci
Joined: 29 Apr 2013 Posts: 13
|
|
Posted: Tue Apr 30, 2013 6:46 pm |
|
|
wow, thank's a lot for this.
i've got to write those information just at startup of system, just one time.
I belive i'm gonna use the first and easier way to store data. i didn't know about the "pages".
Where can i read all pages first address ?
Thank's a lot again
edit: i'm trying but nothing works :(... here is the code:
Code: |
void main()
{
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
...
read_program_memory(0x1ff800, test, 2);
if((test[0]=='O')&&(test[1]=='K'))
{
...switch on a led...
}
...parts of code...
int8 duebyte[2] = {'O','K'};
write_program_memory(0x1ff800, duebyte, 2);
}
|
it should be right like that... or not !? :( |
|
|
|
|
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
|