CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Use the whole word for storing data

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Miniman



Joined: 30 Apr 2007
Posts: 44

View user's profile Send private message

Use the whole word for storing data
PostPosted: Fri Oct 17, 2008 11:03 am     Reply with quote

Hi
I wonder if it is possible to use the whole 14-bit word (PIC16F616) to store data in a constant (or some other way)?
Like this:
const int8 list[*] = {0x44, 0xff};
But with values up to 14-bits long and then use them in the program to calculate some stuff. The data does not need to be written during runtime, it only needs to be read.
Hope you understand what I wish to accomplish

BR Mattias
Ttelmah
Guest







PostPosted: Fri Oct 17, 2008 12:28 pm     Reply with quote

How old is your compiler?.
For older versions, code has been posted here in the past. For V4 releases, declare the const, as _char_, not int8. The compiler will then automatically generate code to combine two 7bit characters into a single 14bit value.

Best Wishes
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Oct 17, 2008 5:19 pm     Reply with quote

The CCS manual says the #rom statement can take a 'char' qualifier to
pack two chars per ROM word.

The program below has the following output.
Quote:
Data = A B


Code:
#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#define DATA_ADDRESS 0x200

#rom char DATA_ADDRESS = {"AB"}

//======================================
void main(void)
{
int16 data;

read_program_memory(DATA_ADDRESS, &data, 2);

printf("Data = %c %c \n\r", data & 0x7F, (data >> 7) & 0x7F );


while(1);
}

Because "AB" is a string, the compiler also uses the ROM word at 0x201
to store the string terminator of 0x00.
Miniman



Joined: 30 Apr 2007
Posts: 44

View user's profile Send private message

PostPosted: Sat Oct 18, 2008 3:00 am     Reply with quote

Thanks for the help!
Ttelmah wrote:
How old is your compiler?

I use 4.038.

PCM programmer, I do not get your program to work.. I get an error on "#rom char DATA_ADD..." Expression must evaluate to a constant. If I put const before char I get the same error. Is my compiler too old then?

thanks for your help!

Br Mattias
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Oct 18, 2008 11:52 am     Reply with quote

I tested 4.038 just now and I found that your version doesn't support
the 'char' feature for #rom. However in the past, before CCS added
that feature, a forum member posted code to pack two 7-bit characters
into each 14-bit ROM word. That post was on the old forum and is not
currently available online. Luckily, I saved it to my hard disk. I found
it, and here it is:
======================================
Posted by Keith Lockstone, 12/14/2001, 12:14:50

Just finished some code that saves ~50% space when sending
messages to the serial port. It was commissioned on a 16F887.
The code is pulled straight from the program, but it should be
self explanatory.
Any thoughts?

Code:

//-------------------------------------------------------------
// *** First define some useful names ***
//-------------------------------------------------------------

#DEFINE OK_MSG 0x1FCE
#DEFINE UNK_CMD_MSG 0x1FD0
#DEFINE LEN_ERR_MSG 0x1FD8
#DEFINE NUM_ERR_MSG 0x1FE3
#DEFINE HEX_ERR_MSG 0x1FEA
#DEFINE RNG_ERR_MSG 0x1FEF
#DEFINE UNK_ERR_MSG 0x1FF9


//-------------------------------------------------------------
// *** Then pack the messages up in the following fashion ***
//-------------------------------------------------------------

#ROM 0x1FCE = {(128*'O'+'K'), 0 } // OK

#ROM 0x1FD0 = {(128*'U'+'n'), (128*'k'+'n'), (128*'o'+'w'), (128*'n'+' '), (128*'C'+'o'),
(128*'m'+'m'), (128*'a'+'n'), (128*'d') } // Unknown Command

#ROM 0x1FD8 = {(128*'W'+'r'), (128*'o'+'n'), (128*'g'+' '), (128*'C'+'o'), (128*'m'+'m'),
(128*'a'+'n'), (128*'d'+' '), (128*'L'+'e'), (128*'n'+'g'),
(128*'t'+'h'), 0 } // Wrong Command Length

#ROM 0x1FE3 = {(128*'N'+'u'), (128*'m'+'e'), (128*'r'+'i'), (128*'c'+' '), (128*'E'+'r'),
(128*'r'+'o'), (128*'r') } // Numeric Error

#ROM 0x1FEA = {(128*'H'+'e'), (128*'x'+' '), (128*'E'+'r'), (128*'r'+'o'),
(128*'r') } // Hex Error

#ROM 0x1FEF = {(128*'N'+'u'), (128*'m'+'b'), (128*'e'+'r'), (128*' '+'o'), (128*'u'+'t'),
(128*' '+'o'), (128*'f'+' '), (128*'R'+'a'), (128*'n'+'g'),
(128*'e') } // Number out of Range

#ROM 0x1FF9 = {(128*'U'+'n'), (128*'k'+'n'), (128*'o'+'w'), (128*'n'+' '), (128*'E'+'r'),
(128*'r'+'o'), (128*'r') } // Unknown Error


//-------------------------------------------------------------
// *** This routine unpacks and transmits the messages ***
//-------------------------------------------------------------
void put_ee_text(long addr) // transmit packed messages from flash
{ int ch; // unpacked character
long adr, // program memory address
xl; // packed characters

adr = addr; // copy address

while (1) // forever
{ xl = read_program_eeprom(adr++); // get packed data, auto inc address

ch = make8(xl << 1, 1); // unpack first character

if (ch == 0) break; // if null, exit
putc(ch); // transmit first character

ch = xl & 127; // unpack second character
if (ch == 0) break; // if null, exit
putc(ch); // transmit second character
}
}

//------------------------------------------------------------
// *** Typical usage from some of own software ***
//------------------------------------------------------------
void send_err_msg(int err) // messages after command completion
{
switch ( err )
{ case 0: break; // no error, no message

case 1: put_ee_text(OK_MSG); // OK message only
break;

case 2: put_ee_text(UNK_CMD_MSG); // Unknown Command
break; // don't type with fingers crossed

case 3: put_ee_text(LEN_ERR_MSG); // Wrong Command Length
break; // don't lean on the keybored

case 4: put_ee_text(NUM_ERR_MSG); // Numeric Error
break; // not all digits

case 5: put_ee_text(HEX_ERR_MSG); // Hex Error
break; // the spell's gone wrong

case 6: put_ee_text(RNG_ERR_MSG); // Number out of Range
break; // cowboys on the loose

default: put_ee_text(UNK_ERR_MSG); // unknown error number
}
send_crlf();
}
John P



Joined: 17 Sep 2003
Posts: 331

View user's profile Send private message

PostPosted: Sun Oct 19, 2008 9:45 pm     Reply with quote

Another way to do this, if you're willing to fool around at that level, is to write the data into a HEX file and load it to the processor in the usual way. You can write a program on your computer to write the file, or maybe an ingenious person could do it using a spreadsheet.

You do need to be careful about exactly where in program ROM your data will be loaded to, so that you don't wipe out your program, and also, you have to be sure that the program can find it. But I have done this and I assure you it can work.

Note that HEX files, being Intel-influenced, are little-endian. The data is stored in a totally non-intuitive way. But it's not there for humans to read.
Miniman



Joined: 30 Apr 2007
Posts: 44

View user's profile Send private message

PostPosted: Tue Oct 28, 2008 11:50 am     Reply with quote

Ohh, I see. Thanks for the answers!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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