How do I define a data table in C18?

blueroomelectronics

Well-Known Member
I'm still really new with C18 but here goes.

I would like to define a table for a IR remote transmitter in C18
The table would contain
IR KHz modulation, mark, space, mark, space,... ,0 (end)

mark and space are the IR on and off times in ms
0 = end of this data stream

Also I would like to know how to address multiple tables, can they be varying in length?
Lastly can I insert formula for some of the data and let the C18 compiler sort out the answer?
 
C Data Structures in Array's

Bill - could what i've pasted below be an example of what you are asking?

(Sorry - i'm a novice at this thing and don't know how to post code so it looks purdy)

David


// Define the structure of one table entry
typedef struct {
unsigned char mark;
unsigned char space;
// Add more stuff if you need it - bits, arrays or anything you want
} BILLSIRRemoteTableStructure;

// Define a Variable & initialize it that uses this structure


BILLSIRRemoteTableStructure iBillsTable[] = { // Initialize table with values
{1,20},
{2,40},
{3,50},
{0,0} // Mark End of data
};

void DoSomething(int mark, int space);

main()
{
int counter;

// Scans through table and does something with each value
// Not such a good example because it would also
// do something with the last value
for(counter=0;counter<sizeof(iBillsTable)/sizeof(BILLSIRRemoteTableStructure);++counter)
DoSomething(iBillsTable[counter].mark,iBillsTable[counter].space);

// Scans through table until sees a 0x00 for mark & space
for(counter=0;iBillsTable[counter].mark!=0 && iBillsTable[counter].space!=0;++counter)
DoSomething(iBillsTable[counter].mark,iBillsTable[counter].space);

}

void DoSomething(int xmark, int xspace)
{
return;
}
 
blueroomelectronics said:
Thanks, I'm an assembler guy trying to learn C. That gives me the framework I need.
BTW you can put static arrays in flash or eeprom. Thats what I did with my font for the GLCD. It was eatin up all the ram, and since it was never going to change (it's static) I told the compiler to put it in program memory.

Like this:
Code:
rom char *alpha1 = {
	0x3e,0x51,0x49,0x45,0x3e,	//0
	0x00,0x42,0x7f,0x40,0x00,	//1
	0x72,0x49,0x49,0x49,0x46,	//2
	0x22,0x49,0x49,0x49,0x36,	//3
	0x0f,0x08,0x08,0x7f,0x08,	//4
	0x2f,0x49,0x49,0x49,0x31,	//5
	0x3e,0x49,0x49,0x49,0x32,	//6
	0x41,0x21,0x11,0x09,0x07,	//7
	0x36,0x49,0x49,0x49,0x36,	//8
	0x26,0x49,0x49,0x49,0x3e};	//9

The "rom" tells the compiler that you want it stored in flash.
 
Thanks Bill... That example from your DS51295E document doesn't seem to be in my DS51295F document... I guess I didn't realize there was that big a difference in document revisions...
 
I couldn't work out how you would use that example either and the above pdf doesn't seem to answer the problem.

The pdf suggests it should be,
Code:
rom char [COLOR="Red"]alpha1[] [/COLOR]= {
	0x3e,0x51,0x49,0x45,0x3e,	//0
	0x00,0x42,0x7f,0x40,0x00,	//1
	0x72,0x49,0x49,0x49,0x46,	//2
	0x22,0x49,0x49,0x49,0x36,	//3
	0x0f,0x08,0x08,0x7f,0x08,	//4
	0x2f,0x49,0x49,0x49,0x31,	//5
	0x3e,0x49,0x49,0x49,0x32,	//6
	0x41,0x21,0x11,0x09,0x07,	//7
	0x36,0x49,0x49,0x49,0x36,	//8
	0x26,0x49,0x49,0x49,0x3e};	//9

You can then do alpha1[3] etc to access it.

Mike.
 
Is this not how it's done? Why the "return roots[val];"

Code:
#include <p18f452.h> /* for 'PRODL' declaration and 'ACCESS' macro */
/*
* Locate the read-only table in program memory at address 0x1000.
* 'romdata' is used for data, and 'code' is used for instructions.
*/
#pragma romdata ROOT_TABLE = 0x1000
#define TABLE_SIZE 100
const rom unsigned char roots[TABLE_SIZE] =
{ 0, 1, 1, 1, 2, 2, 2, 2, 2, 3,
3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
4, 4, 4, 4, 4, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
/*
* Data in access ram does not require banking.
* When compiled with -Oa, these pragmas and the near qualifier may
* be removed.
*/
#pragma udata access MY_ACS_DATA
near unsigned char root, square;
#pragma udata /* continue allocating static data in non-access ram */
/*
* Returns the truncated root of the value.
*/
unsigned char get_root (int val)
{
return roots[val];
}
void main (void)
{
static int val;
for (val = 0; val < TABLE_SIZE; val++)
{
/* 'square' holds the greatest perfect square less than or
* equal to 'val' */
square = get_root (val);
}
}
 
Mike said:
Thank you Futz. Can you show me how you access a char in that const rom array please?
I see I left out the brackets! It works anyway. Here's a couple lines of the working code:
Code:
for(stripe=0;stripe<5;stripe++)			//letter stripe loop
	{
		data_write(alpha1[index]);	//write letters
		index++;			//increment stripe pointer
The compiler didn't warn at all. Compiled clean. Go figure...
 
futz said:
I see I left out the brackets!

You left out the brackets but you inserted a * which turns it into a pointer. If it would compile you would end up with the data somewhere in rom and a variable called alpha1 that held the address of the first byte. When I try to compile it I get 2 errors.

Edit, Futz, are you saying it worked with the rom char *alpha1 = { definition. If so, was alpha1 defined beforehand?

Mike.
 
Ah, here it is. From the BoostC manual:

So it's legal in BoostC, but maybe not in other compilers.
 
You might accuse me of being a purist - but to reduce errors i'd suggest you let the compiler keep track of miniscule stuff like the size of an array - so instead of:

Code:
#define TABLE_SIZE 100
const rom unsigned char roots[TABLE_SIZE] =
{ 0, 1, 1, 1, 2, 2, 2, 2, 2, 3,
3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
4, 4, 4, 4, 4, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };



Code:
const rom unsigned char roots[] =
{ 0, 1, 1, 1, 2, 2, 2, 2, 2, 3,
3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
4, 4, 4, 4, 4, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };

#define TABLE_SIZE  sizeof(roots)

sizeof() always returns the size in bytes - so if it's an array of bytes you are good to go.

if it was an array of integers (16 bit value in the case of a PIC i think?) you would say:

Code:
#define TABLE_SIZE  sizeof(roots)/sizeof(int)

Just one less Constant you have to manually update is all - in the case of your example it comes back with the correct answer either way.
 
Oops! I didn't realize we were talking about two different C compilers either.

Thank you for all the clarifications guys. I'm going to try and change the RAM array to a constant ROM array in that old DayOfWeek() routine...
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…