|
|
View previous topic :: View next topic |
Author |
Message |
ROBOTICAR
Joined: 28 Aug 2007 Posts: 45
|
constant array problem ! |
Posted: Mon Jul 26, 2010 9:31 am |
|
|
Hi all.
I want to print constant array but not directly and in main(). ! In this code I used pointer and I think print_data() work while I define F8_18 in RAM.
my question is here : why I can't get result correctly ?
(I think i must use read_program_memory() . am i right?)
Code: | #include "main.h"
#org 5000,5210
int const F8_12[210]={
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0C, 0xC0, 0x03, 0x38, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xF8, 0x03, 0xFC, 0x07, 0x06, 0x0C, 0x02, 0x08, 0x06, 0x0C, 0xFC, 0x07, 0xF8, 0x03, 0x00, 0x00,
0x00, 0x00, 0x04, 0x08, 0x04, 0x08, 0xFE, 0x0F, 0xFE, 0x0F, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00,
0x08, 0x08, 0x0C, 0x0C, 0x06, 0x0E, 0x86, 0x0D, 0xFE, 0x0C, 0x3C, 0x0C, 0x00, 0x06, 0x00, 0x00,
0x08, 0x02, 0x04, 0x04, 0x46, 0x0C, 0x66, 0x0C, 0xFE, 0x0C, 0xDC, 0x07, 0x80, 0x03, 0x00, 0x00,
0x80, 0x03, 0x40, 0x03, 0x20, 0x03, 0x18, 0x03, 0xFC, 0x0F, 0xFE, 0x0F, 0x00, 0x03, 0x00, 0x00,
0x20, 0x02, 0x3C, 0x04, 0x36, 0x0C, 0x36, 0x0C, 0x66, 0x0C, 0xE6, 0x07, 0xC2, 0x03, 0x00, 0x00,
0xE0, 0x03, 0xF8, 0x07, 0x3C, 0x0C, 0x26, 0x08, 0x66, 0x0C, 0xC2, 0x07, 0x82, 0x03, 0x00, 0x00,
0x0C, 0x00, 0x06, 0x00, 0x06, 0x0C, 0x86, 0x0F, 0xF6, 0x03, 0x7E, 0x00, 0x0E, 0x00, 0x00, 0x00,
0x1C, 0x03, 0xBE, 0x07, 0x73, 0x0C, 0x63, 0x0C, 0xE3, 0x0C, 0xFE, 0x07, 0x9C, 0x03, 0x00, 0x00,
0x38, 0x00, 0x7C, 0x08, 0xC6, 0x0C, 0x82, 0x06, 0x86, 0x07, 0xFC, 0x03, 0xF8, 0x00, 0x00, 0x00,
};
void print_data(int *I,int16 size)
{
int16 S;
for(s=0;s<size;s++)
printf("D[%ld]=%x\r\n",s,I[s]);
}
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
////////////////////////////////////////////////////////////////////////////////
print_data(*F8_12,210);
} |
|
|
|
collink
Joined: 08 Jan 2010 Posts: 137 Location: Michigan
|
|
Posted: Mon Jul 26, 2010 10:11 am |
|
|
Yeah, you should use read_program_memory. The below should work for you:
Code: |
#include "main.h"
#org 5000,5210
int const F8_12[210]={
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0C, 0xC0, 0x03, 0x38, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xF8, 0x03, 0xFC, 0x07, 0x06, 0x0C, 0x02, 0x08, 0x06, 0x0C, 0xFC, 0x07, 0xF8, 0x03, 0x00, 0x00,
0x00, 0x00, 0x04, 0x08, 0x04, 0x08, 0xFE, 0x0F, 0xFE, 0x0F, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00,
0x08, 0x08, 0x0C, 0x0C, 0x06, 0x0E, 0x86, 0x0D, 0xFE, 0x0C, 0x3C, 0x0C, 0x00, 0x06, 0x00, 0x00,
0x08, 0x02, 0x04, 0x04, 0x46, 0x0C, 0x66, 0x0C, 0xFE, 0x0C, 0xDC, 0x07, 0x80, 0x03, 0x00, 0x00,
0x80, 0x03, 0x40, 0x03, 0x20, 0x03, 0x18, 0x03, 0xFC, 0x0F, 0xFE, 0x0F, 0x00, 0x03, 0x00, 0x00,
0x20, 0x02, 0x3C, 0x04, 0x36, 0x0C, 0x36, 0x0C, 0x66, 0x0C, 0xE6, 0x07, 0xC2, 0x03, 0x00, 0x00,
0xE0, 0x03, 0xF8, 0x07, 0x3C, 0x0C, 0x26, 0x08, 0x66, 0x0C, 0xC2, 0x07, 0x82, 0x03, 0x00, 0x00,
0x0C, 0x00, 0x06, 0x00, 0x06, 0x0C, 0x86, 0x0F, 0xF6, 0x03, 0x7E, 0x00, 0x0E, 0x00, 0x00, 0x00,
0x1C, 0x03, 0xBE, 0x07, 0x73, 0x0C, 0x63, 0x0C, 0xE3, 0x0C, 0xFE, 0x07, 0x9C, 0x03, 0x00, 0x00,
0x38, 0x00, 0x7C, 0x08, 0xC6, 0x0C, 0x82, 0x06, 0x86, 0x07, 0xFC, 0x03, 0xF8, 0x00, 0x00, 0x00,
};
void print_data(const int *I,int16 size)
{
int16 s;
int8 temp;
for(s=0;s<size;s++) {
temp = read_program_memory(I + s);
printf("D[%ld]=%x\r\n",s,temp);
}
}
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
////////////////////////////////////////////////////////////////////////////////
print_data(F8_12,210);
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Mon Jul 26, 2010 10:49 am |
|
|
No.....
Problem is that when you store a constant array in memory, it _does not_ start at the beginning of the area declared to hold it. The compiler places the program to retrieve the values here, followed by the values themselves.
There are a number of answers acccording to what you really need.
First, the function 'label_address', will return the actual address in memory where the array is stored. You can then use 'read_program_memory' starting at this location to access the data.
In fact the array won't fit in the area declared, because of this extra code....
Second though, if you store the array using #ROM, rather than 'const', the array will be placed directly in the program memory, without the access code.
Third thing though is that on the latter compilers, you can use pointers to an array declared like this....
So the original code, won't compile, since the array + access code, won't fit in the area defined (remember you need #org default after the array to switch the memory useage back to normal....).
The 'answer' won't work, because you can't hand the address of the array like this, and the read_program_memory function, does not return a value, instead requiring an _address_ to put it's result into.
Simplest answer, use rom, instead of const, get rid of the ORG statement, and let the compiler handle things for you.
Other answer, enlarge the space enough for the extra code, use 'label_address' to get the memory address involved, and hand this as a simple int16/32 (depending on the processor memory size), to the function.
Best Wishes |
|
|
collink
Joined: 08 Jan 2010 Posts: 137 Location: Michigan
|
|
Posted: Mon Jul 26, 2010 11:38 am |
|
|
Whoops... I guess I should have mentioned that. I do use #DEVICE CONST=ROM in my code. Also, I was mixing up read_program_memory and read_program_eeprom. read_program_eeprom works the way I showed. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Mon Jul 26, 2010 2:50 pm |
|
|
I actually don't like using 'CONST=ROM'. I think it is better to use the ROM keyword, and keep 'const' with it's normal meaning. Having multiple meanings to one keyword, is asking for problems latter with working out what is going on...
However, using this (either const=ROM, or int8 rom as the data declaration), then you can use:
Code: |
void print_data(int16 addr,int16 size)
{
int16 s;
int8 temp;
for(s=0;s<size;s++) {
temp=*(rom *)(addr+s);
printf("D[%ld]=%x\r\n",s,temp);
}
}
//and for the call in main:
print_data(F8_12,210);
|
There is however a 'problem'. If you do this, the array still won't be put at the #ORG location. Don't know why, but CCS ignores an ORG on a rom array...
However I'd suggest this is probably 'reliable':
Code: |
#define F8_12 (5000)
#org F8_12,F8_12+210
#rom int8 F8_12={
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0C, 0xC0, 0x03, 0x38, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xF8, 0x03, 0xFC, 0x07, 0x06, 0x0C, 0x02, 0x08, 0x06, 0x0C, 0xFC, 0x07, 0xF8, 0x03, 0x00, 0x00,
0x00, 0x00, 0x04, 0x08, 0x04, 0x08, 0xFE, 0x0F, 0xFE, 0x0F, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00,
0x08, 0x08, 0x0C, 0x0C, 0x06, 0x0E, 0x86, 0x0D, 0xFE, 0x0C, 0x3C, 0x0C, 0x00, 0x06, 0x00, 0x00,
0x08, 0x02, 0x04, 0x04, 0x46, 0x0C, 0x66, 0x0C, 0xFE, 0x0C, 0xDC, 0x07, 0x80, 0x03, 0x00, 0x00,
0x80, 0x03, 0x40, 0x03, 0x20, 0x03, 0x18, 0x03, 0xFC, 0x0F, 0xFE, 0x0F, 0x00, 0x03, 0x00, 0x00,
0x20, 0x02, 0x3C, 0x04, 0x36, 0x0C, 0x36, 0x0C, 0x66, 0x0C, 0xE6, 0x07, 0xC2, 0x03, 0x00, 0x00,
0xE0, 0x03, 0xF8, 0x07, 0x3C, 0x0C, 0x26, 0x08, 0x66, 0x0C, 0xC2, 0x07, 0x82, 0x03, 0x00, 0x00,
0x0C, 0x00, 0x06, 0x00, 0x06, 0x0C, 0x86, 0x0F, 0xF6, 0x03, 0x7E, 0x00, 0x0E, 0x00, 0x00, 0x00,
0x1C, 0x03, 0xBE, 0x07, 0x73, 0x0C, 0x63, 0x0C, 0xE3, 0x0C, 0xFE, 0x07, 0x9C, 0x03, 0x00, 0x00,
0x38, 0x00, 0x7C, 0x08, 0xC6, 0x0C, 0x82, 0x06, 0x86, 0x07, 0xFC, 0x03, 0xF8, 0x00, 0x00, 0x00
}
#org default
void print_data(int16 addr,int16 size)
{
int16 s;
int8 temp;
for(s=0;s<size;s++) {
read_program_memory(addr,&temp,1);
printf("D[%ld]=%x\r\n",s,temp);
}
}
//addr needs to be an int32, if using a part with more than 64K ROM
//Then call from main with:
print_data(F8_12,210);
|
Using #ROM, simply declares a data 'table' at the specified address, rather than an 'array'.
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
|