How do I define a data table in C18?

Status
Not open for further replies.

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?
 
Look up arrays in your C book. Look at structs too. A C guru will give you better answers than me though.
 
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.
 
Sorry, I was still on C18. I must get around to playing with boostC.

Mike.
 
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...
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…