![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
jojos
Joined: 30 Apr 2007 Posts: 64
|
Not enough RAM for all variables problem |
Posted: Wed Oct 03, 2007 7:19 am |
|
|
Hello i am facing the compiler error "Not enough RAM for all variables"
As i saw at compile's help it says that i have to split big functions e.t.c.
I 've done that but nothing happens.Also i removed any uncessary variable.
Here is my code:
Code: |
#include "C:\SmallPicTimer\16F876A.h"
#include <string.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP //INTERNAL OSCILLATOR NO CLOCK
#use delay(clock=4000000)
//#bit rele1=5.1
//#define rele1 GPIO.1
//#define rele2 GPIO.2
#bit G_RES = PORTB.1
#bit G_RS = PORTB.2
#bit G_CLOCK = PORTB.4
#bit G_DATA = PORTB.5
#bit button1 = PORTC.7
#bit button2 = PORTC.6
#bit button3 = PORTC.5
int16 Button(int16 ,int16 ,int16 );
void Bin2Bcd(char);
void init(void);
void lcdinit(void);
void send(int8);
void delay(void);
//void display(void);
//void entire_display_on_off(void);
//void blink(void);
void Show_Numbers(char ,char);
void Get_Numbers(char );
void lcd_clear(void);
void lcd_clear_line(char);
void set_page(char);
//void send_pulse(int1 );
void Get_Middle(char word);
void othoni1(void);
void Menu(void);
void code(void);
void set_column(char);
unsigned char data;
unsigned int n,c;
unsigned char x,BcdHigh,BcdLow,test=0;
char Ringel[]=" RINGEL ELECTRONICS ",
Space[]=" ",WaterText[]="W A T E R = m{" ,
FreqText[]="F R E Q = KHz";
char HydroText[]= "H Y D R O M E T E R",
FreqMeterText[]= "F R E Q . _ M E T E R",
MenuText[]="S E T T I N G S";
/*
};
*/
#include "C:\SmallPicTimer\graphics.c"
void main(void)
{
delay_ms(500);
init();
lcdinit();
Menu();
glcd_text57(WaterText, 1);
loop1:
set_column(12);
Bin2Bcd(test);
Show_Numbers(BcdHigh ,BcdLow);
delay_ms(1000);
if(test==99)
test=0;
test++;
goto Loop1;
//goto lp;
//blink();
//delay_ms(1000);
//}
while(1);
}
void init(void)
{
PORTA=0;
PORTB=0;
PORTC=0;
TRISA=0;
TRISB=0;
TRISC=0b11100000;
return;
}
void send(int8 var)
{
char d0,d1,d2,d3,d4,d5,d6,d7;
d0=(var & 0b1)/1;
d1=(var & 0b10)/2;
d2=(var & 0b100)/4;
d3=(var & 0b1000)/8;
d4=(var & 0b10000)/16;
d5=(var & 0b100000)/32;
d6=(var & 0b1000000)/64;
d7=(var & 0b10000000)/128;
G_DATA=d7;G_CLOCK=1;G_CLOCK=0;
G_DATA=d6;G_CLOCK=1;G_CLOCK=0;
G_DATA=d5;G_CLOCK=1;G_CLOCK=0;
G_DATA=d4;G_CLOCK=1;G_CLOCK=0;
G_DATA=d3;G_CLOCK=1;G_CLOCK=0;
G_DATA=d2;G_CLOCK=1;G_CLOCK=0;
G_DATA=d1;G_CLOCK=1;G_CLOCK=0;
G_DATA=d0;G_CLOCK=1;G_CLOCK=0;
/*
send_pulse(d0);send_pulse(d1);
send_pulse(d2);send_pulse(d3);
send_pulse(d4);send_pulse(d5);
send_pulse(d6);send_pulse(d7);
*/
}
/*
void send_pulse(int1 p)
{
G_DATA=p;
G_CLOCK=1;
G_CLOCK=0;
}
G_DATA=d7;G_CLOCK=1;G_CLOCK=0;
G_DATA=d6;G_CLOCK=1;G_CLOCK=0;
G_DATA=d5;G_CLOCK=1;G_CLOCK=0;
G_DATA=d4;G_CLOCK=1;G_CLOCK=0;
G_DATA=d3;G_CLOCK=1;G_CLOCK=0;
G_DATA=d2;G_CLOCK=1;G_CLOCK=0;
G_DATA=d1;G_CLOCK=1;G_CLOCK=0;
G_DATA=d0;G_CLOCK=1;G_CLOCK=0;
*/
//delay();
//}
void delay(void)
{
for (n=0;n<20;n++)
{
}
}
void lcdinit(void)
{
char k;
//OSCCON=21; //117
//CMCON0=7;
//ANSEL=0;
//TRISIO=8;
///////// G_RS=RS (REGISTER SELECT)(pin5)
///////// G_CLOCK=CLK (pin3)
///////// G_DATA=SID (DATA) (pin2)
///////// G_RES=RESET (pin6)
G_RES=0;
G_RS=0;
G_DATA=0;
G_CLOCK=0;
for (k=0;k<200;k++)
{
delay();
}
G_RES=1;
delay_ms(10);
//////////// Initialization of Lcd /////////
send(0xE2); // SOFTWARE RESET
delay_ms(10);
//delay();delay();delay();//
send(0xA1); // ADC SELECT
send(0xC0); // SHL SELECT
send(0xA2); // LCD BIAS SELECT
send(0x2C);delay();// VC ON
send(0x2E);delay();// VR ON
send(0x2F);delay();// VF ON
send(0x26); // REGULATOR SELECT 26
delay();delay();delay();//
send(0x81); // REFERENCE VOLTAGE MODE
delay();delay();delay();
send(0x10); // COEFFICIENT
delay();delay();delay();
//////////// DATA /////////////////////
send(0x40); // INITIAL LINE 40
send(0xB0); // PAGE B0
send(0x10); // COL ADDRESS 10 MSB
send(0x00); // 00 LSB
send(0xAF); //DISPLAY ON AF
send(0xA6); //Display gets Black and the letters appear white
G_RS=1;
}
/////////////////////////////////////////////////
void Menu(void)
{
char CodeText[]="E N T E R C O D E : " ;
Get_Middle(MenuText);
glcd_text57(MenuText, 1);
set_page(2);
glcd_text57(CodeText, 1);
delay_ms(100);
code();
}
int16 Button(int16 k,int16 orioH,int16 orioL)
{
if(button2==0)
{
k++;
//if(button1==0 &&button3==0)
//k+=10;
if(k>orioH)
k=orioL;
}
else
if(button3==0)
{
k--;
//if( button2==0 &&button3==0)
//k-=10;
if(k<orioL || k>orioH)
k=orioH;
}
return(k);
}
//////////////////////////////////////////////
void code(void)
{
char y1,y2,y3,
CodeCorrect[]="C O D E O.K";
while(!button1)
{
y1=Button(y1,9,0);
Get_Numbers(y1);
}
delay_ms(300);
while(!button1)
{
y2=Button(y1,9,0);
Get_Numbers(y2);
}
delay_ms(300);
while(!button1)
{
y3=Button(y1,9,0);
Get_Numbers(y3);
}
delay_ms(300);
if(y1==1&&y2==2&&y3==3)
{
set_page(4);
set_column(0);
glcd_text57(CodeCorrect, 1);
}
}
///////////////////////////////////////////////
void Bin2Bcd(char x)
{
BcdHigh=x/10; ///Decades
BcdLow=x%10;
exit:
return;
}
//////////////////////////
void Show_Numbers(char High,char Low)
{
Get_Numbers(High);
Get_Numbers(Low);
return;
}
void Get_Numbers(char Num)
{
char r=0;
for(r=0;r<5;r++)
send(FONT[Num+16][r]);
}
//void Show Custom
void lcd_clear(void)
{
char l,b;
for(l=0;l<8;l++)
{
set_page(l);
for(b=0;b<26;b++)
glcd_text57(Space, 1);
}
}
void lcd_clear_line(char row)
{
char y;
set_page(row);
for(y=0;y<26;y++)
glcd_text57(Space, 1);
}
void set_page(char pg)
{
if(pg>7)
pg=7;
G_RS=0;
send((pg+0xB0));
send(0x10); // COL ADDRESS 10 MSB
send(0x00); // 00 LSB
G_RS=1;
}
//////////////////////////////////////////////////////
//Παίρνει ως είσοδο πόσα γραμματα -1 θέλει να μεταφερθεί
//Ένα γράμμα =5 pixel οριζόντια//////////////////////
///
void set_column(char colum)
{
char debug;
//colum-=1;
colum*=5; //convert to pixel
if(colum>124)
colum=124;
debug=(( colum >> 4 ) & 0x0F);
G_RS=0;
//send(0x40); // INITIAL LINE 40
//send(0xB0); // PAGE B0
send(debug|0b00010000);
send((colum&15));
G_RS=1;
}
void Get_Middle(char word)
{
char w_length;
w_length=strlen(word);
set_column(13-(w_length/2));
}
//////////////////////////////////
void othoni1(void)
{
Get_Middle(HydroText);
glcd_text57(HydroText, 1);
}
|
I also use this external file:
Code: |
int8 const FONT[51][5] ={0x00, 0x00, 0x00, 0x00, 0x00, // SPACE
0x00, 0x00, 0x5F, 0x00, 0x00, // !
0x00, 0x03, 0x00, 0x03, 0x00, // "
0x14, 0x3E, 0x14, 0x3E, 0x14, // #
0x24, 0x2A, 0x7F, 0x2A, 0x12, // $
0x43, 0x33, 0x08, 0x66, 0x61, // %
0x36, 0x49, 0x55, 0x22, 0x50, // &
0x00, 0x05, 0x03, 0x00, 0x00, // '
0x00, 0x1C, 0x22, 0x41, 0x00, // (
0x00, 0x41, 0x22, 0x1C, 0x00, // )
0x14, 0x08, 0x3E, 0x08, 0x14, // *
0x08, 0x08, 0x3E, 0x08, 0x08, // +
0x00, 0x50, 0x30, 0x00, 0x00, // ,
0x08, 0x08, 0x08, 0x08, 0x08, // -
0x00, 0x60, 0x60, 0x00, 0x00, // .
0x20, 0x10, 0x08, 0x04, 0x02, // /
0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
0x00, 0x04, 0x02, 0x7F, 0x00, // 1
0x42, 0x61, 0x51, 0x49, 0x46, // 2
0x22, 0x41, 0x49, 0x49, 0x36, // 3
0x18, 0x14, 0x12, 0x7F, 0x10, // 4
0x27, 0x45, 0x45, 0x45, 0x39, // 5
0x3E, 0x49, 0x49, 0x49, 0x32, // 6
0x01, 0x01, 0x71, 0x09, 0x07, // 7
0x36, 0x49, 0x49, 0x49, 0x36, // 8
0x26, 0x49, 0x49, 0x49, 0x3E, // 9
0x00, 0x36, 0x36, 0x00, 0x00, // :
0x00, 0x56, 0x36, 0x00, 0x00, // ;
0x08, 0x14, 0x22, 0x41, 0x00, // <
0x14, 0x14, 0x14, 0x14, 0x14, // =
0x00, 0x41, 0x22, 0x14, 0x08, // >
0x02, 0x01, 0x51, 0x09, 0x06, // ?
0x3E, 0x41, 0x59, 0x55, 0x5E, // @
0x7E, 0x09, 0x09, 0x09, 0x7E, // A
0x7F, 0x49, 0x49, 0x49, 0x36, // B
0x3E, 0x41, 0x41, 0x41, 0x22, // C
0x7F, 0x41, 0x41, 0x41, 0x3E, // D
0x7F, 0x49, 0x49, 0x49, 0x41, // E
0x7F, 0x09, 0x09, 0x09, 0x01, // F
0x3E, 0x41, 0x41, 0x49, 0x3A, // G
0x7F, 0x08, 0x08, 0x08, 0x7F, // H
0x00, 0x41, 0x7F, 0x41, 0x00, // I
0x30, 0x40, 0x40, 0x40, 0x3F, // J
0x7F, 0x08, 0x14, 0x22, 0x41, // K
0x7F, 0x40, 0x40, 0x40, 0x40, // L
0x7F, 0x02, 0x0C, 0x02, 0x7F, // M
0x7F, 0x02, 0x04, 0x08, 0x7F, // N
0x3E, 0x41, 0x41, 0x41, 0x3E, // O
0x7F, 0x09, 0x09, 0x09, 0x06, // P
0x1E, 0x21, 0x21, 0x21, 0x5E, // Q
0x7F, 0x09, 0x09, 0x09, 0x76};// R
int8 const FONT2[44][5]={0x26, 0x49, 0x49, 0x49, 0x32, // S
0x01, 0x01, 0x7F, 0x01, 0x01, // T
0x3F, 0x40, 0x40, 0x40, 0x3F, // U
0x1F, 0x20, 0x40, 0x20, 0x1F, // V
0x7F, 0x20, 0x10, 0x20, 0x7F, // W
0x41, 0x22, 0x1C, 0x22, 0x41, // X
0x07, 0x08, 0x70, 0x08, 0x07, // Y
0x61, 0x51, 0x49, 0x45, 0x43, // Z
0x00, 0x7F, 0x41, 0x00, 0x00, // [
0x02, 0x04, 0x08, 0x10, 0x20, // \
0x00, 0x00, 0x41, 0x7F, 0x00, // ]
0x04, 0x02, 0x01, 0x02, 0x04, // ^
0x40, 0x40, 0x40, 0x40, 0x40, // _
0x00, 0x01, 0x02, 0x04, 0x00, // `
0x20, 0x54, 0x54, 0x54, 0x78, // a
0x7F, 0x44, 0x44, 0x44, 0x38, // b
0x38, 0x44, 0x44, 0x44, 0x44, // c
0x38, 0x44, 0x44, 0x44, 0x7F, // d
0x38, 0x54, 0x54, 0x54, 0x18, // e
0x04, 0x04, 0x7E, 0x05, 0x05, // f
0x08, 0x54, 0x54, 0x54, 0x3C, // g
0x7F, 0x08, 0x04, 0x04, 0x78, // h
0x00, 0x44, 0x7D, 0x40, 0x00, // i
0x20, 0x40, 0x44, 0x3D, 0x00, // j
0x7F, 0x10, 0x28, 0x44, 0x00, // k
0x00, 0x41, 0x7F, 0x40, 0x00, // l
0x7C, 0x04, 0x78, 0x04, 0x78, // m
0x7C, 0x08, 0x04, 0x04, 0x78, // n
0x38, 0x44, 0x44, 0x44, 0x38, // o
0x7C, 0x14, 0x14, 0x14, 0x08, // p
0x08, 0x14, 0x14, 0x14, 0x7C, // q
0x00, 0x7C, 0x08, 0x04, 0x04, // r
0x48, 0x54, 0x54, 0x54, 0x20, // s
0x04, 0x04, 0x3F, 0x44, 0x44, // t
0x3C, 0x40, 0x40, 0x20, 0x7C, // u
0x1C, 0x20, 0x40, 0x20, 0x1C, // v
0x3C, 0x40, 0x30, 0x40, 0x3C, // w
0x44, 0x28, 0x10, 0x28, 0x44, // x
0x0C, 0x50, 0x50, 0x50, 0x3C, // y
0x44, 0x64, 0x54, 0x4C, 0x44, // z
//0x00, 0x08, 0x36, 0x41, 0x41, // {
0x11, 0x15, 0x1F, 0x00, 0x00, //x3 {
0x00, 0x00, 0x7F, 0x00, 0x00, // |
0x41, 0x41, 0x36, 0x08, 0x00, // }
0x02, 0x01, 0x02, 0x04, 0x02}; // ~
//0x7F, 0x01, 0x01, 0x01, 0x01};// Γ
//const int8 Cust_FONT[1}[5]={0x05,0x07,0x07,0x00,0x00);
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// Purpose: Write text on a graphic LCD
// Inputs: (x,y) - The upper left coordinate of the first letter
// textptr - A pointer to an array of text to display
// size - The size of the text: 1 = 5x7, 2 = 10x14, ...
// color - ON or OFF
/////////////////////////////////////////////////////////////////////////
void glcd_text57(char* textptr, char page)
{
int8 m; // Loop counters
int8 pixelData[5]; // Stores character data
for(; *textptr != '\0'; ++textptr, ++x)// Loop through the passed string
{
if(*textptr < 'S') // Checks if the letter is in the first font array
memcpy(pixelData, FONT[*textptr - ' '], 5);
else if(*textptr <= '~') // Check if the letter is in the second font array
memcpy(pixelData, FONT2[*textptr - 'S'], 5);
else
memcpy(pixelData, FONT[0], 5); // Default to space
for(m=0;m<5;m++)
{
//for(j=0;j<2;j++)
//{
//setpage(page+j);
//set_column(m);
send(pixeldata[m]);
//}
}
}
} |
Sorry for the code size.[/code] |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Wed Oct 03, 2007 8:11 am |
|
|
Wrong error.....
Spliting up the functions, if for the 'not enough _ROM_ error', where it can be caused by the 'parts' of the program simply being too large to fit in the available ROM banks. The _RAM_ error, is different.
For the RAM error, there are three basic causes:
1) On '16' chips in particular, the RAM is organised into pages. These have large areas used by 'system' variables mapped into the same area (hardware feature of the chip - nothing you can do about this). The _largest_ array or variable you define, _must_ fit into the availble space in one bank.
2) Even if the individual variables fit, you can just run out of RAM. The PIC's don't have much...
3) How much RAM you can use, is also limited by the mode you configure the code to use. The limit is only the first page (96bytes), unless you add the *=16 option to your device declaration.
Fortunately, I cannot see the *=16 declaration anywhere in your code, so this should fix the problem, Currently, you just have 96byytes available, and your six text message arrays are using this, without leaving space for anything else....
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Oct 03, 2007 9:05 am |
|
|
An additional hint on saving RAM:
Code: | char HydroText[]= "H Y D R O M E T E R", | This creates the data in RAM but it is very unlikely you ever want to change the text. Change to Code: | const char HydroText[]= "H Y D R O M E T E R", | to read the data from ROM.
There is a restriction though... The CCS compiler can not handle pointers to ROM, only to RAM. This means you will have to copy the data from ROM to a temporary RAM buffer before you can pass it to a function like printf().
The v4.xxx compiler is suppossed to be capable of handling ROM pointers but I don't think this new feature is stable yet. |
|
![](templates/subSilver/images/spacer.gif) |
jojos
Joined: 30 Apr 2007 Posts: 64
|
|
Posted: Wed Oct 03, 2007 9:52 am |
|
|
Thanks for the quick response.How can declare the *16 option?Please give me an example.
Also i dont know if this has to do with my problem but i read somewhere in this forum about enabling the 16bit pointers.What is that and can this help?
Thanks
P.S.
I have the feeling that *16 is the 16bit pointers am i correct? |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Oct 03, 2007 9:58 am |
|
|
Quote: | I have the feeling that *16 is the 16bit pointers am i correct? | Yes
Example Code: | #device PIC16F123
#device *=16 |
or
Code: | #device PIC16F123 *=16 ADC=10 |
Note that *8 (default) results in more efficient ROM code but is limited to using only the first RAM bank. *16 gives access to all available RAM but at the cost of using a bit more ROM.
This directive does nothing for PIC18 processors, these are always using 16 bit pointers. |
|
![](templates/subSilver/images/spacer.gif) |
jojos
Joined: 30 Apr 2007 Posts: 64
|
|
Posted: Wed Oct 03, 2007 10:18 am |
|
|
Thanks again for the response.
![Very Happy](images/smiles/icon_biggrin.gif) |
|
![](templates/subSilver/images/spacer.gif) |
Francois
Joined: 29 Mar 2005 Posts: 2
|
|
Posted: Thu Oct 25, 2007 8:42 am |
|
|
I have the same problem with a pic12CE509 with the use of only 25 variables. So the bank1 is not use by the compiler. What is possible to do tu use the 40 bytes of ram ?
I tried to add *=16 to device declration but the compiler don't accept it.
best regards |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Thu Oct 25, 2007 9:03 am |
|
|
#device *=8
The manual is very poorly written here. The 'options' section, should read something like:
Code: |
Options are qualifiers to the standard operation of the device. Valid options are:
*=5 Use 5 bit pointers (for all parts - default on '12' chips)
*=8 Use 8 bit pointers ('12' and '16' parts - default on '16' chips)
*=16Use 16 bit pointers (for '16' parts - n/a on '18' parts)
|
Best Wishes |
|
![](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
|