![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
bwhiten
Joined: 26 Nov 2003 Posts: 151 Location: Grayson, GA
|
Error, Data Item Too Big |
Posted: Sat Mar 22, 2008 9:09 am |
|
|
Ok, I did a search for the above string but found limited info. on the board. The help file lists this error but blank information.
I'm using 4.069, 16F887.
The issue is:
I have and empty segment that states 2048 free. I am trying to #ORG a constant 2-dimensional array of [80][20] chars into this area but I get the "ERROR 87: Data Item Too Big" error.
What are the limitations on 2-dimensional array indecies or am I mistaking free memory for something it's not? |
|
![](templates/subSilver/images/spacer.gif) |
Matro Guest
|
|
Posted: Sat Mar 22, 2008 9:14 am |
|
|
2048 bytes or word-instructions?
If it is 2048 bytes, it is only 1024 different addresses...
Matro |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Sat Mar 22, 2008 9:51 am |
|
|
Is this data numbers, or text?.
If the latter, then instead look at the #ROM char option.
On the 16F chips, the program memory, is 14bits wide. Each location, can therefore hold just _one_ byte. However it can hold two 7 bit text characters. This is what the #ROM char option implements. So if it is text, you should use this option to make a massive saving in the storage area involved.
Now, each program memory 'page' on this chip, can hold 1024*14bit words, which requires the hex output file to allocate 2048 'bytes'. However because each real location is only 14bits in size, you can't _store_ 2048 bytes here.
So if you need to store 1600 _characters_, then look at the #ROM option, which will pack these into 800 'words' of storage, and fit them into a page. However if you want to hold 1600*8bit values, then you need to think again, since this won't fit (which is what the compiler is complaining about....).
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
bwhiten
Joined: 26 Nov 2003 Posts: 151 Location: Grayson, GA
|
|
Posted: Sat Mar 22, 2008 10:55 am |
|
|
This is my declaration:
Code: |
#ORG 0x01000, 0x017FF
const char TEXTA[80][20] = {0x00,0x0C,....,....,....};
|
So this would not qualify for the 800 words of storage?
I don't see a method to "name" the 2-dimensional array using #ROM in the help guide. What would be the easiest way to access it in a routine, a #define of some sort? |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Sat Mar 22, 2008 11:28 am |
|
|
No, characters by default, will be defined as bytes, so each will occupy an entire instruction word in memory. Worse, the const declaration, will include the code to retrieve it as well, making this occupy quite a few more locations....
Yes. write a 'retrieval' routine, using the read_program_memory function. You will need to extract the seven bit values, and handle calculating the right location in this.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Mar 22, 2008 11:33 am |
|
|
Quote: | You will need to extract the seven bit values. |
CCS has added an option to allow packing two chars per ROM word
for the 16F PICs (not needed for 18F) by using the 'char' keyword in
the #rom statement.
From the Readme.txt file:
Quote: |
A new option has been added to #rom to pack 7 bit characters into the PCM 14 bit word.
For example:
#ROM CHAR 0x1000={"THIS STRING TAKES 22 INSTRUCTION LOCATIONS"}
|
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Sat Mar 22, 2008 3:49 pm |
|
|
I mention this in my first post.
This is what bwhiten was asking about how you retrieve the data from.
You would need something like (no guarantees...):
Code: |
#define ELEMENTS_PER_ROW (20)
#define FIRST_LOC (0x1000)
char get_char(int row, int col) {
int16 address;
static int16 last_address=0;
static int16 val;
int8 temp;
address=FIRST_LOC+((int16)row*(ELEMENTS_PER_ROW/2))+(col/2);
if (address!=last_address) {
//here need to retrieve word at the specified address
val=read_program_eeprom(address);
last_address=address;
}
if (col & 1) {
//Here need the high bits
temp=(val>>7)&0x7F;
}
else {
//Here low seven bits
temp=val&0x7F;
}
return temp;
}
|
This should allow you to access the data using 'get_char(row,col)', and could obviously be encapsulated in a #define if required. It only actually reads the data for every other location, if reading is sequential. Tere is a balancing act, in that reads themselves are quick, so unless reads are likely ot be sequential, it is probably quicker to omit the test, and always perform a read.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
bwhiten
Joined: 26 Nov 2003 Posts: 151 Location: Grayson, GA
|
|
Posted: Sat Mar 22, 2008 7:06 pm |
|
|
Thanks for the help. I have several options now to work on. I'm assuming this works for constants and variable data? |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Sun Mar 23, 2008 7:56 am |
|
|
No.
Variable data has to be stored in RAM, which is 8bits wide. This _only_ applies to constant data stored in the _program_ memory, which on these chips is large enough to store two seven bit values, but not two 8bit values (on the 18 chips, the program memory is wider).
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
bwhiten
Joined: 26 Nov 2003 Posts: 151 Location: Grayson, GA
|
|
Posted: Sun Mar 23, 2008 1:45 pm |
|
|
OK I guess I'm still a little confused. Are the:
"write_program_memory" and "read_program_memory" functions not useable in real-time?
Or am I confusing me/you with "variable" instead of "variable data at a memory location"?
I take it as long as I keep track of where a certain piece of data is I can use the _program_memory functions all day long. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Sun Mar 23, 2008 3:51 pm |
|
|
You can use read_program_eeprom, as much as you want. However the _write_ functions, must be treated with a lot of care. The chip has a limited life for write cycles to this memory. Typically anything from 10000, to 100000 cycles depending on the chip. Also the memory is organised into pages, and a whole page must be erased, and re-written to write just a single byte. The writes are also _slow_ typically in the order of perhaps 4mSec (an age in computer terms).
If you realise that (for example), changing a value once a second, could use up the write life on even the 'better' chips in this regard, in a little over a day, you will begind to understand why writing these values, should only be done as little as possible....
The EEPROM, is specifically designed to store values you want to keep, and should be used in preference (has usually many times the life - typically perhaps 100*).
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
bwhiten
Joined: 26 Nov 2003 Posts: 151 Location: Grayson, GA
|
|
Posted: Sun Mar 23, 2008 6:28 pm |
|
|
Now I understand better. Useable but not meant for repeated writes. Constants or data storage for boot time options I guess would be OK.
The memory areas of these chips have quite a few similar names when you look through the device file, datasheet, etc. The device file alone lists, Program memory, RAM, Data EEPROM. |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|