Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

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?
 
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! :eek: 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! :eek:

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:
Rom
Strings or arrays of data can be placed into program memory.
Such variables are declared using regular data types and rom storage specifier.
Such rom variables must be initialized within declaration:
rom char *text = "Test string"; // text with trailing zero
rom char *ptr = "\0x64\11\12"; // 4 bytes: 0x64, 0x0B, 0x0C, 0x00
rom char *data = { 0x64, 11, 12 }; // 3 data bytes: 0x64, 0x0B, 0x0C
Please keep in mind that the rom storage specifier has several limitations:
• rom can be used with char data types only;
• there is no implicit cast between rom and regular data types. Though BoostC
will not generate an explicit error for such a cast, it is expected that the
operand should be casted back to its original type.
If this is not done, the resulting code will behave unpredictably.
• a rom pointer is internally limited to 8-bits: the constant array size is thus
limited to 256 elements. This is coherent with smaller cores constraints;
• access to rom elements has to be done exclusively through the [] operators
and they cannot be referenced with substring pointer initialized at
runtime. Please keep in mind that rom variables must always and exclusively
be initialized within declaration;

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...
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top