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 5
(136 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 5
(61 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 5
(44 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;
}
}

 

0 Kudos
Message 4 of 5
(24 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

0 Kudos
Message 5 of 5
(21 Views)