From 04:00 PM CDT – 08:00 PM CDT (09:00 PM UTC – 01:00 AM UTC) Tuesday, April 16, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Multisim and Ultiboard

cancel
Showing results for 
Search instead for 
Did you mean: 

Using MCU 8051 in Multisim 14.2 - linker error

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?

 

 

Download All
0 Kudos
Message 1 of 15
(2,960 Views)

 

Hi JasonTurner52,

 

 

Those errors may pertain to limit of direct addressing mode. Can you attach your circuit as inline screenshot image like this, and your C code as inline text like this?

 

 

Best regards,

G. Goodwin

 

0 Kudos
Message 2 of 15
(2,885 Views)

 

Please verify these:

 

  • If you are using 8051 or other derivative which has 128 bytes or less "internal RAM" (e.g., 80C51, 89C51), address 08Ch belongs to SFR space.
  • If you are using 8052 or other derivative which has 256 bytes "internal RAM" (e.g., 80C52, 89C52, 89C55), internal RAM locations 080h to 0FFh can be accessed using Indirect Addressing mode.
  • If variables or registers are mapped to "external data memory" the compiler should be directed about this.

 

I hope you can post more information or updates regarding this problem.

 

0 Kudos
Message 3 of 15
(2,868 Views)

Hi

 

The circuit is:

JasonTurner52_0-1618215368414.png

 

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;
}
}

 

Message 4 of 15
(2,848 Views)

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

Message 5 of 15
(2,845 Views)

 

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_arrc_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.

 

0 Kudos
Message 6 of 15
(2,816 Views)

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.

 

Message 7 of 15
(2,804 Views)

 

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.

 

0 Kudos
Message 8 of 15
(2,784 Views)

Yep same error as before.

0 Kudos
Message 9 of 15
(2,775 Views)

 

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.

 

0 Kudos
Message 10 of 15
(2,757 Views)