04-02-2021 01:26 PM
Hi all
I'm using arrays in the 8051 MCU c code and it's throwing up 4 linker errors:
Error: : 0 psect "rbss" exceeds address limit: 08Ch > 080h
Error: : 0 psect "rdata" exceeds address limit: 08Ch > 080h
Error: : 0 psect "irdata" exceeds address limit: 08Ch > 080h
Error: : 0 psect "idata" exceeds address limit: 08Ch > 080h
I've attached my c code and .ms14 model as well.
Can anyone explain what this means, please?
04-05-2021 03:39 PM
04-06-2021 01:36 PM
Please verify these:
I hope you can post more information or updates regarding this problem.
04-12-2021 03:17 AM
Hi
The circuit is:
Code is here:
/****Interfacing keypad and LCD with 8051 to design a simple calculator***/
#include <htc.h>
/******Function declaration******/
void init(void);
void command(unsigned int);
void write_data(unsigned char);
void delay(unsigned char );
void msDelay(unsigned int);
char process_key(int,int,int,int,char,char,char,char);
void num_generator(char,int *);
void write_result(int,char);
/*********IO used in program*****************/
#define EN P02 // Enable LCD
#define RW P03 // Read Write
#define RS P04 // Register Select
void main()
{
int i, j,*operand, operand1=0, operand2=0 ,result=0;
int i_arr[4][4] = {{0,1,1,1},{1,0,1,1},{1,1,0,1},{1,1,1,0}};
char pressed_key, operator1='a', negative='N';
char c_arr[4][4] = {{'7','4','1','o'},{'8','5','2','0'},{'9','6','3','='},{'+','-','*','/'}}, error[10]={'M','A','T','H',' ','E','R','R','O','R'};
P0 = 0x00;
P1 = 0xff;
operand = &operand1;
while (1)
{
for(i=0; i<4; i++)
{
pressed_key = process_key(i_arr[i][0],i_arr[i][1],i_arr[i][2],i_arr[i][3],c_arr[i][0],c_arr[i][1],c_arr[i][2],c_arr[i][3]);
if(pressed_key=='/'||pressed_key=='*'||pressed_key=='-'||pressed_key=='+')
{
operand = &operand2;
operator1 = pressed_key;
}
if((pressed_key != 'Z')&&(pressed_key!= '=')&&(pressed_key!= '/')&&(pressed_key!= '*')&&(pressed_key!= '-')&&(pressed_key!= '+'))
{
num_generator(pressed_key, operand);
}
if(pressed_key == '=')
if(operator1== '*')
result = operand1*operand2;
if(operator1== '/')
if(operand2==0)
{
command(0xC0);
for(j=0; j<10; j++)
write_data(error[j]);
msDelay(500);
init();
}
else
result = operand1/operand2;
if(operator1== '-')
{
if (operand1>operand2)
result = operand1-operand2;
else
{
result = operand2-operand1;
command(0xC0);
negative = 'Y';
}
}
if(operator1== '+')
{
result = operand1+operand2;
write_result(result,negative);
}
}
}
}
/********************************** LCD initialise function**************************/
void init()
{
delay(3500);
command(0x38);
delay(3500);
command(0x38);
delay(3500);
command(0x38);
delay(350);
command(0x38);
command(0x1C);
command(0x0E);
command(0x06);
command(0x01);
delay(3500);
command(0x00);
}
/*************************Function to send command to LCD***********************/
void command(unsigned int comm)
{
RW=0;
RS=0;
P2=comm;
EN=1;
delay(3500);
EN=0;
}
/*********Function for delay*******************/
void delay(unsigned char c)
{
unsigned int i;
unsigned char j;
for(i=0;i<=3;i++)
{
for(j=0;j<=c;j++);
}
}
/***************Function for delay in milli seconds********************/
void msDelay(unsigned int time)
{
TL0 = 0xEF;
TH0 = 0xAF;
TR0 = 1;
while(time--)
{
while(TF0 == 0);
TF0 = 0;
TL0 = 0xEF;
TH0 = 0xAF;
}
TR0 = 0;
}
/************************Process and check the press of key**********************/
char process_key(int a,int b,int c,int d,char A,char B,char C,char D)
{
char ch = 'Z';
P10=a;
P11=b;
P12=c;
P13=d;
if(P14==0)
{
ch = A;
}
if(P15==0)
{
ch = B;
}
if(P16==0)
{
ch = C;
}
if(P17==0)
{
if(D == 'o')
init();
else
ch = D;
}
if(ch!= 'Z')
{
write_data(ch);
msDelay(100);
}
return ch;
}
/**************************Function write data in char on LCD****************/
void write_data(unsigned char ch)
{
RW = 0;
RS = 1;
P2 = ch;
EN = 1;
delay(3500);
EN = 0;
}
void num_generator(char ch,int *operand)
{
int digit;
digit = ch - '0';
*operand = digit + (*operand*10);
}
void write_result(int num,char neg)
{
int i=0,j,rem;
char rev_num[20];
command(0xC0);
if(neg == 'Y')
{
write_data('-');
}
do
{
rem = num%10;
num = num /10;
rev_num[i] = (char)rem+'0';
i++;
}
while(num>0);
for(j=i-1; j>=0; j--)
{
RW = 0;
RS = 1;
P2 = rev_num[j];
EN = 1;
delay(3500);
EN = 0;
}
}
04-12-2021 03:30 AM
Hi
Thanks for the info about memory mapping. I've tried using the 8052 model with the increased memory size but the gap in my knowledge is how to access the extra memory (or the data memory) using Indirect Addressing mode. Do you know if there's an example I can refer to? There are lots of examples on internet using assembly, far fewer in C and the Hitech compiler seems to have it's own set of rules as well.
Many thanks
04-13-2021 11:01 PM
Indirect addressing uses registers R0 and R1 to hold the address to "internal RAM" (DPTR for "external RAM"). In 8051 assembly language the @ operator denotes indirect addressing, e.g., @R0, @R1. In C it is generally done using the pointer operator *. Thus, we can assume *R0 and *R1 as the counterpart notations but the C compiler can take care of manipulating these registers so that the programmer need only be concerned of where to place the data. It's always a good practice to consult the manual or user's guide of every specific compiler regarding this.
The errors generated by the linker pertain to "internal RAM" limit but it's quite puzzling why it stipulates 08Ch > 080h. 080h is 1 byte above the highest directly addressable "internal RAM" location (07Fh) and 08Ch is several bytes above 07Fh and/or 080h.
Temporarily replace the 8051 with 8052 and try running the code/circuit. If the errors persist, proceed below but post any change(s) in error messages.
If the minimum stack size specification is relatively large, try reducing it by 13 bytes. Some 8051 C compilers have a default stack size of just 1, I don't know the default in Hi-tech C. If there is no GUI-based facility for adjusting the settings you may need to modify the startup file(s) in Hi-tech. Refer to Multisim and Hi-tech manuals for guidance. I don't have Multisim (Desktop) application and the low-end smartphone I'm using has problem opening pdf files so I can't perform experiment on your circuit and code and I can't open manuals or user's guide.
You have substantial amount of data that don't change but are stored as variables, try converting them into constants. For example, precede the declarations of i_arr, c_arr, and error with const. In some systems such as in PC this is not so important but in small microcontrollers such as the 8051 it can make a difference.
04-14-2021 04:10 AM
Thanks for that. I've changed to the 8052 and it reduces the errors to:
Multisim - 14 April 2021, 10:02:58
-------------------------Building: Project: Calculator--------------------------
Note: -E compiler option was not present. This option has been added to the compiler build command temporarily.
Note: -O compiler option was not present. This option has been added to the compiler build command temporarily.
Compiler results: 0 - Errors, 0 - Warnings
Linking...
Error: : 0 psect "rbss" exceeds address limit: 08Ch > 080h
Error: : 0 psect "rdata" exceeds address limit: 08Ch > 080h
Linker results: 2 - Errors, 0 - Warnings
The changed from int to const seems to cause more problems as well. I can't seem to find any way to force the model to increase or reallocate the memory. I'll keep hunting.
04-15-2021 04:32 PM
Did you do it like these?
const int i_arr[4][4] = {{0,1,1,1},{1,0,1,1},{1,1,0,1},{1,1,1,0}};
const char c_arr[4][4] = {{'7','4','1','o'},{'8','5','2','0'},{'9','6','3','='},{'+','-','*','/'}};
const char error[10]={'M','A','T','H',' ','E','R','R','O','R'};
You can post the error messages as ATTACHMENT(S) if you like.
Anyway, whether you've done it as above or not, you may still want to try modifying your declarations like these:
code int i_arr[4][4] = {{0,1,1,1},{1,0,1,1},{1,1,0,1},{1,1,1,0}};
code char c_arr[4][4] = {{'7','4','1','o'},{'8','5','2','0'},{'9','6','3','='},{'+','-','*','/'}};
code char error[10]={'M','A','T','H',' ','E','R','R','O','R'};
I don't have deep knowledge of Hi-tech C, aside from other constraints that I already mentioned in my previous reply, so we have to do this trial and error.
04-16-2021 05:39 AM
Yep same error as before.
04-20-2021 02:29 PM
Using const access modifier can solve the problem in few compiler(s). Using code declaration modifier can solve the problem in some compilers. I hope you want to try again with these:
rom int i_arr[4][4] = {{0,1,1,1},{1,0,1,1},{1,1,0,1},{1,1,1,0}};
rom char c_arr[4][4] = {{'7','4','1','o'},{'8','5','2','0'},{'9','6','3','='},{'+','-','*','/'}};
rom char error[10]={'M','A','T','H',' ','E','R','R','O','R'};
If these don't work you can post the error messages as ATTACHMENT(S) if you like.
The rom declaration modifier is less descriptive for this purpose because ROM simply stands for Read-Only Memory but this may be Hi-tech's approach to this kind of proramming requirement.