Saving RAM with LCD and UART

General discussion on mikroC PRO for PIC.
Author
Message
Mince-n-Tatties
Posts: 2780
Joined: 25 Dec 2008 15:22
Location: Scotland

Saving RAM with LCD and UART

#1 Post by Mince-n-Tatties » 26 Nov 2012 13:30

how to save RAM when using either LCD or UART or both!

Code: Select all

/////////////////////////////////////////////////////////////////////
//
// Demo Of how to save RAM for LCD and UART
// PIC 16F887
// 8Mhz Internal OSC
// UART 9600 BAUD
//
//
// Hardware UART connected at 9600BAUD
// LCD connected in 4 bit mode with RW pin grounded
//



// LCD module connections
sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB1_bit;
sbit LCD_D4 at RB2_bit;
sbit LCD_D5 at RB3_bit;
sbit LCD_D6 at RB4_bit;
sbit LCD_D7 at RB5_bit;

sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB4_bit;
sbit LCD_D7_Direction at TRISB5_bit;
// End LCD module connections


char msg[17]; //declare array set to max size required plus 1 [for terminator] for copying into

// copy const to ram string
char * CopyConst2Ram(char * dest, const char * src){
  char * d ;
  d = dest;
  for(;*dest++ = *src++;)
    ;
  return d;
}


const char LCD_txt1[] = "Ram Saving Test.";
const char LCD_txt2[] = "Top Row LCD     ";
const char LCD_txt3[] = "Bottom Row LCD  ";
const char LCD_txt4[] = "UART output.....";
const char UART_txt1[] = "Ram Test 1\r\n";
const char UART_txt2[] = "Ram Test 2\r\n";
const char UART_txt3[] = "Ram Test 3\r\n";
const char UART_txt4[] = "Ram Test 4\r\n";
const char UART_txt5[] = "Ram Test 5\r\n";
const char UART_txt6[] = "Ram Test 6\r\n";
const char UART_txt7[] = "Ram Test 7\r\n";
const char UART_txt8[] = "Ram Test 8\r\n";



void main() {


  OSCCON  = 0x71;       // settings for 8Mhz internal clock

  ANSEL  = 0;           // Configure AN pins as digital
  ANSELH = 0;
  CM1CON0 = 0;          // Disable comparators
  CM2CON0 = 0;          // Disable comparators


  UART1_Init(9600);    // init uart at 9600
  Delay_ms(100);

  Lcd_Init();                        // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);               // Clear display
  Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off

  Lcd_Out(1,1,CopyConst2Ram(msg,LCD_txt1)); // Write text in first row
  Lcd_Out(2,1,CopyConst2Ram(msg,LCD_txt1)); // Write text in second row


  while(1)
   {
       Lcd_Cmd(_LCD_CLEAR);               // Clear display
       Lcd_Out(1,1,CopyConst2Ram(msg,LCD_txt4)); // Write text in first row
       
       Uart1_Write_Text(CopyConst2Ram(msg,UART_txt1));
       Uart1_Write_Text(CopyConst2Ram(msg,UART_txt2));
       Uart1_Write_Text(CopyConst2Ram(msg,UART_txt3));
       Uart1_Write_Text(CopyConst2Ram(msg,UART_txt4));
       Uart1_Write_Text(CopyConst2Ram(msg,UART_txt5));
       Uart1_Write_Text(CopyConst2Ram(msg,UART_txt6));
       Uart1_Write_Text(CopyConst2Ram(msg,UART_txt7));
       Uart1_Write_Text(CopyConst2Ram(msg,UART_txt8));
       Delay_ms(2000);
       Lcd_Out(1,1,CopyConst2Ram(msg,LCD_txt2)); // Write text in first row
       Lcd_Out(2,1,CopyConst2Ram(msg,LCD_txt3)); // Write text in second row
       Delay_ms(2000);
       
    };


}
using a 16F887 for the test numbers...

Used RAM (bytes): 26 (7%) Free RAM (bytes): 326 (93%)
Used ROM (program words): 728 (9%) Free ROM (program words): 7464 (91%)
capture.png
capture.png (21.35 KiB) Viewed 15402 times
Best Regards

Mince

Mince-n-Tatties
Posts: 2780
Joined: 25 Dec 2008 15:22
Location: Scotland

Re: Saving RAM with LCD and UART

#2 Post by Mince-n-Tatties » 26 Nov 2012 13:38

and here is the same code without RAM saving...

Code: Select all

/////////////////////////////////////////////////////////////////////
//
// Demo Of how NOT to save RAM for LCD and UART
// PIC 16F887
// 8Mhz Internal OSC
// UART 9600 BAUD
//
//
// Hardware UART connected at 9600BAUD
// LCD connected in 4 bit mode with RW pin grounded
//



// LCD module connections
sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB1_bit;
sbit LCD_D4 at RB2_bit;
sbit LCD_D5 at RB3_bit;
sbit LCD_D6 at RB4_bit;
sbit LCD_D7 at RB5_bit;

sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB4_bit;
sbit LCD_D7_Direction at TRISB5_bit;
// End LCD module connections



void main() {


  OSCCON  = 0x71;       // settings for 8Mhz internal clock

  ANSEL  = 0;           // Configure AN pins as digital
  ANSELH = 0;
  CM1CON0 = 0;          // Disable comparators
  CM2CON0 = 0;          // Disable comparators


  UART1_Init(9600);    // init uart at 9600
  Delay_ms(100);

  Lcd_Init();                        // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);               // Clear display
  Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off

  Lcd_Out(1,1,"Ram Saving Test."); // Write text in first row
  Lcd_Out(2,1,"Ram Saving Test."); // Write text in second row


  while(1)
   {
       Lcd_Cmd(_LCD_CLEAR);               // Clear display
       Lcd_Out(1,1,"UART output....."); // Write text in first row

       Uart1_Write_Text("Ram Test 1\r\n");
       Uart1_Write_Text("Ram Test 2\r\n");
       Uart1_Write_Text("Ram Test 3\r\n");
       Uart1_Write_Text("Ram Test 4\r\n");
       Uart1_Write_Text("Ram Test 5\r\n");
       Uart1_Write_Text("Ram Test 6\r\n");
       Uart1_Write_Text("Ram Test 7\r\n");
       Uart1_Write_Text("Ram Test 8\r\n");
       
       Delay_ms(2000);
       Lcd_Out(1,1,"Top Row LCD     "); // Write text in first row
       Lcd_Out(2,1,"Bottom Row LCD  "); // Write text in second row
       Delay_ms(2000);

    };


}
this code fails to run properly, because I have run out of compiler accessible RAM. the compiler warns me of this with the irp_bit message below

warning: 0 1511 IRP bit must be set manually for indirect access to '?lstr2_UART_LCD_No_RAM_Saver_1' variable UART_LCD_No_RAM_Saver_1.c
warning: 0 1511 IRP bit must be set manually for indirect access to '?lstr3_UART_LCD_No_RAM_Saver_1' variable UART_LCD_No_RAM_Saver_1.c
warning: 0 1511 IRP bit must be set manually for indirect access to '?lstr4_UART_LCD_No_RAM_Saver_1' variable UART_LCD_No_RAM_Saver_1.c

and here are the RAM/ROM usage stats

Used RAM (bytes): 198 (56%) Free RAM (bytes): 154 (44%)
Used ROM (program words): 691 (8%) Free ROM (program words): 7501 (92%)

notice that there are still 154 bytes of RAM available! that is where the irp_bit comes in. The irp_bit needs to be set by YOU so that this 154 bytes of RAM can be used.

irp_bit is a topic all of it's own. And i suggest that you avoid the problem by using either the ram saving methods offered here (and you will find other options by searching the forum) or by switching to using PIC18 rather than PIC16 with this compiler.
Best Regards

Mince

janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

Re: Saving RAM with LCD and UART

#3 Post by janni » 26 Nov 2012 16:35

Mince-n-Tatties wrote:and here is the same code without RAM saving...
...
and here are the RAM/ROM usage stats

Used RAM (bytes): 198 (56%) Free RAM (bytes): 154 (44%)
Used ROM (program words): 691 (8%) Free ROM (program words): 7501 (92%)
That's when you switch 'dynamic link for string literals' off. Having it on gives even worse figures

Used RAM (bytes): 199 (57%) Free RAM (bytes): 153 (43%)
Used ROM (program words): 817 (10%) Free ROM (program words): 7375 (90%)


This is strange as apparently the dynamic link for string literals option in mC lacks optimization present in mP and mB (reusing of local strings). The same configuration (and code) in mP leads to

Used RAM (bytes): 25 (7%) Free RAM (bytes): 327 (93%)
Used ROM (program words): 780 (10%) Free ROM (program words): 7412 (90%)


without a need for workarounds. There's only one internal local string used (instead of 13 in mC), reloaded every time with new literal string.

ADDED: just made a try at using string constants (i.e. manually copying them to a string variable) in mP and the resulting statistics is

Used RAM (bytes): 26 (7%) Free RAM (bytes): 326 (93%)
Used ROM (program words): 709 (9%) Free ROM (program words): 7483 (91%)


showing improvement only in ROM use.

Mince-n-Tatties
Posts: 2780
Joined: 25 Dec 2008 15:22
Location: Scotland

Re: Saving RAM with LCD and UART

#4 Post by Mince-n-Tatties » 28 Nov 2012 11:25

Hi Janni,

yip i posted on that exact issue previously.

http://www.mikroe.com/forum/viewtopic.p ... %26dynamic
Best Regards

Mince

Mince-n-Tatties
Posts: 2780
Joined: 25 Dec 2008 15:22
Location: Scotland

Re: Saving RAM with LCD and UART

#5 Post by Mince-n-Tatties » 29 Nov 2012 14:42

janni wrote:
Mince-n-Tatties wrote:and here is the same code without RAM saving...
...
and here are the RAM/ROM usage stats

Used RAM (bytes): 198 (56%) Free RAM (bytes): 154 (44%)
Used ROM (program words): 691 (8%) Free ROM (program words): 7501 (92%)
That's when you switch 'dynamic link for string literals' off. Having it on gives even worse figures

Used RAM (bytes): 199 (57%) Free RAM (bytes): 153 (43%)
Used ROM (program words): 817 (10%) Free ROM (program words): 7375 (90%)

you will note that i had switched dynamic link off!

maybe someday mE will resolve both problems.

1. irp_bit needs to be auto handled. this keeps getting in the way for customers and to add insult, the older non pro compiler managed it!

2. the dynamic link RAM usage increase and now Janni has shown the mP compiler is much better than the more expensive mC!

The delta between mP 7% RAM used and mC 56% of RAM used in this specific example is simply unacceptable.
Best Regards

Mince

janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

Re: Saving RAM with LCD and UART

#6 Post by janni » 29 Nov 2012 16:03

Hi Mince,

As far as I remember, the IRP bit was never handled automatically in mP compilers, which is indeed a hindrance when using PIC16s and, looking at the amount of related forum topics, a source of a lot of frustration :( .

I woudn't say that mP and mB are better, even though I prefer mP :wink: . With 'dynamic link for string literals' off, mC uses more code-effective algorithm to assign string literals - though at the cost of storing them all in RAM at program start. Unfortunately, with 'dynamic link for string literals' on, mC does the same as mP/mB compilers do with this option turned off, i.e. copies the strings only before use but without reusing RAM.

Concluding, it would be best to modify all compilers - mP and mB should use the same method as mC with dynamic link off, and mC should apply same method as mP/mB with this option turned on.

Mince-n-Tatties
Posts: 2780
Joined: 25 Dec 2008 15:22
Location: Scotland

Re: Saving RAM with LCD and UART

#7 Post by Mince-n-Tatties » 29 Nov 2012 18:01

janni wrote:Hi Mince,

As far as I remember, the IRP bit was never handled automatically in mP compilers, which is indeed a hindrance when using PIC16s and, looking at the amount of related forum topics, a source of a lot of frustration :( .
It has been a looooonnnngggg time since i used mikroC ver 8 and below, but i am fairly sure irp_bit was auto handled. I would need to look at the ASM of some old projects to confirm. mE guys will know for sure!
janni wrote: I woudn't say that mP and mB are better, even though I prefer mP :wink: . With 'dynamic link for string literals' off, mC uses more code-effective algorithm to assign string literals - though at the cost of storing them all in RAM at program start. Unfortunately, with 'dynamic link for string literals' on, mC does the same as mP/mB compilers do with this option turned off, i.e. copies the strings only before use but without reusing RAM.

Concluding, it would be best to modify all compilers - mP and mB should use the same method as mC with dynamic link off, and mC should apply same method as mP/mB with this option turned on.
my stand point is just simply that the compiler product range cannot produce such a disparity in performance especially in this area, RAM usage on 8 bit MCU's and be accepted.

mE guys really need to take a sledge hammer to these two items and put them to bed forever!
Best Regards

Mince

janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

Re: Saving RAM with LCD and UART

#8 Post by janni » 29 Nov 2012 18:11

Mince-n-Tatties wrote:mE guys really need to take a sledge hammer to these two items and put them to bed forever!
Agreed :) .

User avatar
janko.kaljevic
Posts: 3565
Joined: 16 Jun 2011 13:48

Re: Saving RAM with LCD and UART

#9 Post by janko.kaljevic » 30 Nov 2012 15:07

Hello,

At the moment I can confirm that IRP bit managing will stay as it is for now.
We will consider it for some future releases.

mikroC and mikroPascal use two different mechanisms regarding string literals.

mP reuses local temp string var, but loads it char by char before usage. This usually generates bigger code, but consumes less ram.

mC uses more local temp string var, but initializes them in a loop upon routine entering. That is why all local temp strings exist while you are inside the routine. This usually, generates smaller and faster code, but consumes more ram.

We'll see to improve both mc and mp algorithms.

Literal strings are not always stored in RAM. Compiler will store them in flesh memory if you pass them to const char pointers.
You could make wrapper routines for library functions.
i.e.

Code: Select all

void LCD_Out_const(char x, char y, const char *txt){
char loc_text[__MAX_STRING_LENGTH];
char * dst;

  dst = loc_text;
  while (*dst++ = *txt++)
    ;

  LCD_Out(x, y, loc_text);
}
This can be used as workaround to save RAM in these situations.

Best regards.

MARIO
Posts: 978
Joined: 18 Aug 2008 22:13
Location: Brasil

Re: Saving RAM with LCD and UART

#10 Post by MARIO » 01 Dec 2012 13:50

Mince wrote:1. irp_bit needs to be auto handled. this keeps getting in the way for customers and to add insult, the older non pro compiler managed it!
Agreed.
Mince wrote:It has been a looooonnnngggg time since i used mikroC ver 8 and below, but i am fairly sure irp_bit was auto handled. I would need to look at the ASM of some old projects to confirm. mE guys will know for sure!
You are right, Mince. This is very true. It was auto handled.
BR
EasyPic6 and registered mkC PRO FOR PIC since 2011
You're never too old to learn something stupid.(PARAPROSDOKIAN)

janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

Re: Saving RAM with LCD and UART

#11 Post by janni » 02 Dec 2012 00:53

MARIO wrote:It was auto handled.
Which mC version did that?

MARIO
Posts: 978
Joined: 18 Aug 2008 22:13
Location: Brasil

Re: Saving RAM with LCD and UART

#12 Post by MARIO » 02 Dec 2012 03:15

@janni

mC 8.2.0.0. I think that was the last version before Pro, I don't know previous ones.

EDIT: I remembered that it only works if array is indexed by a constant not a var (suppose var is in bank 3 or 4).
LCD_Chr(1,1, var[4]); works fine.
but:
i = 4;
LCD_Chr(1,1, var); doesn't work.
BR
EasyPic6 and registered mkC PRO FOR PIC since 2011
You're never too old to learn something stupid.(PARAPROSDOKIAN)

janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

Re: Saving RAM with LCD and UART

#13 Post by janni » 02 Dec 2012 13:30

Hi MARIO,

I'm afraid, it was not IRP handling, but just direct access of higher memory banks. I have found this topic indicating that the IRP bit problem was simply passed to mC PRO from mC. Naturally, besides checking my memory, this discussion is rather academic now :) . It does not matter that much whether IRP auto handling is restored or formed anew, as long as it's done ending the flow of posts from alarmed users finding that their code doesn't work.

p.erasmus
Posts: 3391
Joined: 05 Mar 2009 10:28

Re: Saving RAM with LCD and UART

#14 Post by p.erasmus » 02 Dec 2012 13:33

Yes This problem is al old as mikro compilers in my opinion it is just one of the issues that will never be resolved
although all other compiler competitors are doing this mE fails to see the issue .
P.Erasmus
Saratov,Russia
--------------------------------------------------------------

MARIO
Posts: 978
Joined: 18 Aug 2008 22:13
Location: Brasil

Re: Saving RAM with LCD and UART

#15 Post by MARIO » 02 Dec 2012 13:59

janni wrote:It does not matter that much whether IRP auto handling is restored or formed anew, as long as it's done ending the flow of posts from alarmed users finding that their code doesn't work.
Yes, I agree. As I have been told long time ago, if you can detect it you can solve it. See this post: http://www.mikroe.com/forum/viewtopic.php?f=88&t=46471
But it seems not to be resolved by mE team, as janko posted and peter confirmed. :(
BR
EasyPic6 and registered mkC PRO FOR PIC since 2011
You're never too old to learn something stupid.(PARAPROSDOKIAN)

Post Reply

Return to “mikroC PRO for PIC General”