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 support@ccsinfo.com

Printing Character Strings

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







Printing Character Strings
PostPosted: Thu Mar 20, 2003 2:09 pm     Reply with quote

My application requires several constant strings to be printed to an LCD.

The compiler generates so much code for every string I need to print that I am running out of code space! Why does the compiler generate separate function calls for each character to be printed? Is it because the compiler does not allow pointers to constant data?

Is it possible to do the following and save some ROM?:

byte const str[11]= {"Some str "};

void Print_Array(char ptr)
{
char i;
char c;

for(i=0; i<10; i++)
{
c = ptr[i];
LCD_Write(c, LCD_DATA);
}
}

void main()
{
Print_Array(str);
}

Any ideas are welcome!
Charlie
___________________________
This message was ported from CCS's old forum
Original Post ID: 12892
R.J.Hamlett
Guest







Re: Printing Character Strings
PostPosted: Thu Mar 20, 2003 3:54 pm     Reply with quote

:=My application requires several constant strings to be printed to an LCD.
:=
:=The compiler generates so much code for every string I need to print that I am running out of code space! Why does the compiler generate separate function calls for each character to be printed? Is it because the compiler does not allow pointers to constant data?
:=
:=Is it possible to do the following and save some ROM?:
:=
:=byte const str[11]= {"Some str "};
:=
:=void Print_Array(char ptr)
:={
:= char i;
:= char c;
:=
:= for(i=0; i<10; i++)
:= {
:= c = ptr[i];
:= LCD_Write(c, LCD_DATA);
:= }
:=}
:=
:=void main()
:={
:= Print_Array(str);
:=}
:=
:=Any ideas are welcome!
:=Charlie
There is a shortcut in the CCS C, which does what you need, and is a lot more compact, than using printf.

void send(char) {
LCD_Write(c, LCD_DATA);
}

//Then when you need to print a string, you can use:
send("My constant string");

This should be smaller than either other alternative.

Best Wishes
___________________________
This message was ported from CCS's old forum
Original Post ID: 12897
Charlie
Guest







Re: Printing Character Strings
PostPosted: Thu Mar 20, 2003 5:36 pm     Reply with quote

Thanks for the response. But, your suggestion is what I am doing already in the code and it just eats up way too much storage memory. Is there any other way to do this?

Will my idea of sending the address of the first element to a function and then letting the function index through the constant string work?

Thanks.


:=:=My application requires several constant strings to be printed to an LCD.
:=:=
:=:=The compiler generates so much code for every string I need to print that I am running out of code space! Why does the compiler generate separate function calls for each character to be printed? Is it because the compiler does not allow pointers to constant data?
:=:=
:=:=Is it possible to do the following and save some ROM?:
:=:=
:=:=byte const str[11]= {"Some str "};
:=:=
:=:=void Print_Array(char ptr)
:=:={
:=:= char i;
:=:= char c;
:=:=
:=:= for(i=0; i<10; i++)
:=:= {
:=:= c = ptr[i];
:=:= LCD_Write(c, LCD_DATA);
:=:= }
:=:=}
:=:=
:=:=void main()
:=:={
:=:= Print_Array(str);
:=:=}
:=:=
:=:=Any ideas are welcome!
:=:=Charlie
:=There is a shortcut in the CCS C, which does what you need, and is a lot more compact, than using printf.
:=
:=void send(char) {
:= LCD_Write(c, LCD_DATA);
:=}
:=
:=//Then when you need to print a string, you can use:
:=send("My constant string");
:=
:=This should be smaller than either other alternative.
:=
:=Best Wishes
___________________________
This message was ported from CCS's old forum
Original Post ID: 12904
Tomi
Guest







Re: Printing Character Strings
PostPosted: Fri Mar 21, 2003 4:30 am     Reply with quote

<font face="Courier New" size=-1>If you use 18F series then you can access the ROM as data ROM by a simple TableRead instruction (TBLPTR acts as an index register, post-and-pre-increments and -decrements are included). I use these various functions:
// array to store string addresses (when the strings have different sizes)
const unsigned long strings[] = {0x0800,0x0810,0x0820};

#ROM 0x0800 = {"First string"} // constant strings
#ROM 0x0810 = {"2nd string"}
#ROM 0x0820 = {"3rd string"}

#byte TBLPTRU = 0xFF8 // some definitions
#byte TBLPTRH = 0xFF7
#byte TBLPTRL = 0xFF6
#byte TABLAT = 0xFF5

void DisplayFixedLengthString(char idx,char length)
{
unsigned long addr;
char i,maxchars,data;
#byte addrL = addr
#byte addrH = addr+1

maxchars = length;
addr = 0x0800 + idx*length;
TBLPTRU = 0;
TBLPTRH = addrH;
TBLPTRL = addrL;
do {
#asm
TBLRD*+
#endasm
data = TABLAT;
if (!data) break; // terminating NULL is reached
putchar(data);
} while (--maxchars);
}

void DisplayVarLengthString(char idx)
{
unsigned long addr;
char i,maxchars,data;
#byte addrL = addr
#byte addrH = addr+1

maxchars = 16;
addr = strings[idx];
TBLPTRU = 0;
TBLPTRH = addrH;
TBLPTRL = addrL;
do {
#asm
TBLRD*+
#endasm
data = TABLAT;
if (!data) break;
putchar(data);
} while (--maxchars);
}

// to display a ROM string from address "addr"
void DisplayStringAtAddress(unsigned long addr,char maxchars)
{
char i,data;
#byte addrL = addr
#byte addrH = addr+1

TBLPTRU = 0;
TBLPTRH = addrH;
TBLPTRL = addrL;
do {
#asm
TBLRD*+
#endasm
data = TABLAT;
if (!data) break;
putchar(data);
} while (--maxchars);
}

Usage:
DisplayFixedLengthString(0,16);
printf("\r\n");
DisplayFixedLengthString(1,16);
printf("\r\n");
DisplayVarLengthString(0);
printf("\r\n");
DisplayVarLengthString(1);
printf("\r\n");
DisplayStringAtAddress(0x0820,16);
printf("\r\n");


:=My application requires several constant strings to be printed to an LCD.
:=
:=The compiler generates so much code for every string I need to print that I am running out of code space! Why does the compiler generate separate function calls for each character to be printed? Is it because the compiler does not allow pointers to constant data?
:=
:=Is it possible to do the following and save some ROM?:
:=
:=byte const str[11]= {"Some str "};
:=
:=void Print_Array(char ptr)
:={
:= char i;
:= char c;
:=
:= for(i=0; i<10; i++)
:= {
:= c = ptr[i];
:= LCD_Write(c, LCD_DATA);
:= }
:=}
:=
:=void main()
:={
:= Print_Array(str);
:=}
:=
:=Any ideas are welcome!
:=Charlie ___________________________
This message was ported from CCS's old forum
Original Post ID: 12913
R.J.Hamlett
Guest







Re: Printing Character Strings
PostPosted: Fri Mar 21, 2003 5:31 am     Reply with quote

:=Thanks for the response. But, your suggestion is what I am doing already in the code and it just eats up way too much storage memory. Is there any other way to do this?
:=
:=Will my idea of sending the address of the first element to a function and then letting the function index through the constant string work?
:=
:=Thanks.
No.
Fundamental statement. You cannot have pointers to constants in the CCS C.
The routine as descibed, should _not_ use that much code space. Basically there is a single overhead 'block' for the constant string (which contains the setup to return the character specified), and the routine should simply call this for each character in the string.
The exception is for the latter (18F etc.) chips, where the 'table read' functions are used instead.
The 'overhead', is only four characters for the entire string, plus three characters to setup the print call, and three characters to test for the final '\0' character and handle the branch on this.
The only way you could do the indexed call, would be if the chip you are using supports the 'read_program_eeprom' function, and you define all your constant strings into one block of memory, and hand the address in this block to the function, and use this call to walk through the block.

Best Wishes

:=:=:=My application requires several constant strings to be printed to an LCD.
:=:=:=
:=:=:=The compiler generates so much code for every string I need to print that I am running out of code space! Why does the compiler generate separate function calls for each character to be printed? Is it because the compiler does not allow pointers to constant data?
:=:=:=
:=:=:=Is it possible to do the following and save some ROM?:
:=:=:=
:=:=:=byte const str[11]= {"Some str "};
:=:=:=
:=:=:=void Print_Array(char ptr)
:=:=:={
:=:=:= char i;
:=:=:= char c;
:=:=:=
:=:=:= for(i=0; i<10; i++)
:=:=:= {
:=:=:= c = ptr[i];
:=:=:= LCD_Write(c, LCD_DATA);
:=:=:= }
:=:=:=}
:=:=:=
:=:=:=void main()
:=:=:={
:=:=:= Print_Array(str);
:=:=:=}
:=:=:=
:=:=:=Any ideas are welcome!
:=:=:=Charlie
:=:=There is a shortcut in the CCS C, which does what you need, and is a lot more compact, than using printf.
:=:=
:=:=void send(char) {
:=:= LCD_Write(c, LCD_DATA);
:=:=}
:=:=
:=:=//Then when you need to print a string, you can use:
:=:=send("My constant string");
:=:=
:=:=This should be smaller than either other alternative.
:=:=
:=:=Best Wishes
___________________________
This message was ported from CCS's old forum
Original Post ID: 12915
Charlie
Guest







Re: Printing Character Strings
PostPosted: Fri Mar 21, 2003 4:25 pm     Reply with quote

Thanks to everyone for the feedback! I'm programming a 16c773 device, BTW.

I noticed a huge improvement when I used the #SEPARATE preprocessor command before a function that was being INLINED by the compiler, even though this function was used in several places in the code. After using the #SEPARATE command, all my calls to print strings shrunk!? I saved about 12\% code space!

It now works like R.J. Hamlett said it would...but before the #SEPARATE command all the calls were HUGE! More than 40+ assembly lines of code to print 10 characters!

Thanks a million guys!

:=My application requires several constant strings to be printed to an LCD.
:=
:=The compiler generates so much code for every string I need to print that I am running out of code space! Why does the compiler generate separate function calls for each character to be printed? Is it because the compiler does not allow pointers to constant data?
:=
:=Is it possible to do the following and save some ROM?:
:=
:=byte const str[11]= {"Some str "};
:=
:=void Print_Array(char ptr)
:={
:= char i;
:= char c;
:=
:= for(i=0; i<10; i++)
:= {
:= c = ptr[i];
:= LCD_Write(c, LCD_DATA);
:= }
:=}
:=
:=void main()
:={
:= Print_Array(str);
:=}
:=
:=Any ideas are welcome!
:=Charlie
___________________________
This message was ported from CCS's old forum
Original Post ID: 12936
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