|
|
View previous topic :: View next topic |
Author |
Message |
SeeCwriter
Joined: 18 Nov 2013 Posts: 160
|
Using Array Pointers |
Posted: Tue Apr 29, 2014 12:23 pm |
|
|
I'm using a 12LF1552 with v5.025 compiler. My program has two arrays consisting of 10 32-bit integers declared as such:
Code: |
const u32 lowband_data[] = {
0x02000004,
0x0300008C,
0x05006095,
0x062003CA,
0x0700044D,
0x0809BEFF,
0x098DBFFF,
0x0A002205,
0x0B0F8071,
0x0F000081
};
const u32 highband_data[] = {
0x02000004,
0x03000091,
0x05006095,
0x062003CA,
0x07000C4D,
0x0809BEFF,
0x098DBFFF,
0x0A002205,
0x0B078071,
0x0F000081
};
|
What I found that doesn't work is to use a pointer to access the arrays. For example, this does not work:
Code: |
u32 *pReg;
void main()
{
Init();
while( TRUE ) {
pReg = ( input( BAND_SELECT ) ) ? highband_data:lowband_data;
ProgramDevice( pReg );
sleep();
}
}
void ProgramDevice( u32 *p )
{
int nRegs, Reg;
nRegs = sizeof(lowband_data) >> 2; // Number of regs to program
for ( Reg = 0; Reg < nRegs; Reg++) {
SetReg( p[Reg] );
delay_us(10);
}
}
void SetReg( u32 data )
{
...
}
|
What does work is this:
Code: |
void main()
{
byte high_band;
Init();
while( TRUE ) {
high_band = ( input( BAND_SELECT ) ) ? 1:0;
ProgramDevice( high_band );
sleep();
}
}
void ProgramDevice( byte high_band )
{
int nRegs, Reg;
nRegs = sizeof(lowband_data) >> 2; // Number of regs to program
for ( Reg = 0; Reg < nRegs; Reg++) {
if ( high_band ) SetReg( highband_data[Reg] );
else SetReg( lowband_data[Reg] );
delay_us(10);
}
}
|
I think both methods should work, or did I do something wrong with the first method? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Tue Apr 29, 2014 12:54 pm |
|
|
A search here would have found the answer.
The PIC (unlike most processors), has a separate memory space for ROM, and RAM. Const values are stored in ROM. Normal variables in RAM.
Pointers point to the RAM address space.
On the 'bigger' PIC's, there is an option to use the rom keyword, instead of const, and then the compiler will generate the extra code to allow pointers to be constructed to these values. You have to declare the pointer as a rom pointer as well.
However this is quite bulky, and on your small PIC, might not be useable.
Code: |
rom u32 highband_data[] = {
0x02000004,
0x03000091,
0x05006095,
0x062003CA,
0x07000C4D,
0x0809BEFF,
0x098DBFFF,
0x0A002205,
0x0B078071,
0x0F000081
};
//and the pointer as
rom u32 *pReg;
|
|
|
|
SeeCwriter
Joined: 18 Nov 2013 Posts: 160
|
|
Posted: Tue Apr 29, 2014 1:18 pm |
|
|
Good point. But I think the compiler should have at least thrown a warning about an incompatible type assignment. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Tue Apr 29, 2014 2:41 pm |
|
|
Not really. There is nothing incompatible, it just doesn't work!....
C has no type checking inbuilt. You can assign a number between types completely flexibly. The language will convert types if it can, but it is up to you as a user to check that numbers are compatible. So (for instance), there is nothing to stop you having a signed number, and then printing this with the %u printf format.
The same applies with the memory spaces. Both have addresses in the same range. You could use the address of a value in ROM, and then use the read_program_memory function to access the value. Though there is a caveat here that a const _may_ have extra data in front of it that is not actually the value. |
|
|
|
|
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
|