![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
Miniman
Joined: 30 Apr 2007 Posts: 44
|
Use the whole word for storing data |
Posted: Fri Oct 17, 2008 11:03 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Fri Oct 17, 2008 12:28 pm |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Oct 17, 2008 5:19 pm |
|
|
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.
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. |
|
![](templates/subSilver/images/spacer.gif) |
Miniman
Joined: 30 Apr 2007 Posts: 44
|
|
Posted: Sat Oct 18, 2008 3:00 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Oct 18, 2008 11:52 am |
|
|
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();
} |
|
|
![](templates/subSilver/images/spacer.gif) |
John P
Joined: 17 Sep 2003 Posts: 331
|
|
Posted: Sun Oct 19, 2008 9:45 pm |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
Miniman
Joined: 30 Apr 2007 Posts: 44
|
|
Posted: Tue Oct 28, 2008 11:50 am |
|
|
Ohh, I see. Thanks for the answers! |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|