Hello friends, today's post is about designing a simple calculator with 8051 Microcontroller. In our previous post, we have seen How to Interface keypad with 8051 Microcontroller in Proteus ISIS. Moreover, we have also worked on Interfacing of LCD with 8051 Microcontroller in Proteus ISIS. If you haven't read these two posts then my suggestion is to read them first before going into the details of this post, as we are going to use both keypad and LCD in order to design the simple calculator with 8051 Microcontroller.

#### Design a Simple Calculator with 8051 Microcontroller

• The calculator we are going to design in this post is quite basic calculator, it will only perform 4 tasks, which are as follows:
• When you press the (+) button then it will add the two digits. For example, you want to add 2 and 3 then you need to press 2 + 2 = these four buttons in sequence and when you press the = button it will automatically will give you the sum.
• When you press (-) button it will subtract the two digits like 3 - 2 = and it will give you the result.
• When you press (x) button it will multiply the two digits.
• When you press the (/) button it will simply divide the two digits.
• Whenever you press the (=) button, it will give you the output depending on the function you used before and if you press (=) in the start then it will give "Wrong Input".
• Finally, there's (ON/C) button on the Calculator, when you press this it will simply reset the code and will clear the LCD.
• So, that's how this calculator is gonna work. Moreover, it will always reset when you try to calculate new value.
• As its a simple calculator, so its only limited to 1 digit, means it will only apply the operation on single digit input like 2+3 but it won't work on more than 1 digit like 12 + 13.
• I will soon design a more complicated calculator but for this one its only limited to single digit.
• So, now let's design this calculator, so first we are gonna have a look at the Proteus simulation of Simple calculator with 8051 Microcontroller.
• After that, we will do the coding part for calculator with 8051 Microcontroller.
• So, now let's get started with Proteus Simulation.
##### Proteus Simulation
• So, you can see we have used the same LCD which is 20x4 and have used the same keypad as did in previous tutorial.
• You can see this keypad has all the required operations for this project which are (+), (-), (x) and (/).
• So, now let's have a look at the programming code for calculator with 8051 Microcontroller.
##### Programming Code
• We have already seen the programming code for keypad and LCD and I am assuming that you have also read those posts so I am not going into the details of those posts.
• So,we know that how to print data on LCD and we are also aware of how to get key press from keypad and then display it on LCD.
• So, now let's move on to adding these functions.
```while(1)
{
//get numb1
key = get_key();
writecmd(0x01);            //clear display
writedata(key);            //Echo the key pressed to LCD
num1 = get_num(key);       //Get int number from char value, it checks for wrong input as well

if(num1!=Error)            //if correct input then proceed, num1==Error means wrong input
{
//get function
key = get_key();
writedata(key);                  //Echo the key pressed to LCD
func = get_func(key);            //it checks for wrong func

if(func!='e')                    //if correct input then proceed, func=='e' means wrong input
{
//get numb2
key = get_key();
writedata(key);              //Echo the key pressed to LCD
num2 = get_num(key);         //Get int number from char value, it checks for wrong input as well

if(num2!=Error)              //if correct input then proceed, num2==Error means wrong input
{
//get equal sign
key = get_key();
writedata(key);          //Echo the key pressed to LCD

if(key == '=')           //if = is pressed then proceed
{
switch(func)         //switch on function
{
case '+': disp_num(num1+num2); break;
case '-': disp_num(num1-num2); break;
case 'x': disp_num(num1*num2); break;
case '/': disp_num(num1/num2); break;
}
}
else				      //key other then = here means error wrong input
{
if(key == 'C')       //if clear screen is pressed then clear screen and reset
writecmd(0x01);   //Clear Screen
else
DispError(0); 	  //Display wrong input error
}
}
}
}
}```
• As you can see in the above function, I have first check for the first key press.
• When you pressed the first key on keypad then I get this key and converter it to integer.
• After that I waited for the next key which must be some operation key like + - X or / otherwise it will generate the error message.
• After that code is waiting for the third key which should be some numerical digit and then I converter it to integer again and if you entered some invalid key then it will generate the error.
• Finally waiting for the = sign. When you press the = sign it will automatically perform the required operation which I placed in the switch case loop.
• It will calculate the value and then print out the result and on next key press it will first clear the screen and then get the value and will continue.
• Below is the detailed code for the project with comments and I hope you wont get into any trouble and will get it clearly.
```#include<reg51.h>
#include<string.h>

//Define Macros
#define Error  13    // Any value other than 0 to 9 is good here

//Function declarations
void cct_init(void);
void delay(int);
void lcdinit(void);
void writecmd(int);
void writedata(char);
void writeline(char[]);
void ReturnHome(void);
char get_key(void);
int get_num(char);
char get_func(char);
void DispError(int);
void disp_num(int);
void WebsiteLogo();

//*******************
//Pin description
/*
P2 is data bus
P3.7 is RS
P3.6 is E
P1.0 to P1.3 are keypad row outputs
P1.4 to P1.7 are keypad column inputs
*/
//********************
// Define Pins
//********************
sbit RowA = P1^0;     //RowA
sbit RowB = P1^1;     //RowB
sbit RowC = P1^2;     //RowC
sbit RowD = P1^3;     //RowD

sbit C1   = P1^4;     //Column1
sbit C2   = P1^5;     //Column2
sbit C3   = P1^6;     //Column3
sbit C4   = P1^7;     //Column4

sbit E    = P3^6;     //E pin for LCD
sbit RS   = P3^7;     //RS pin for LCD

// ***********************************************************
// Main program
//
int main(void)
{
char key;                     //key char for keeping record of pressed key
int num1 = 0;                 //First number
char func = '+';              //Function to be performed among two numbers
int num2 = 0;                 //Second number

cct_init();                   //Make input and output pins as required
lcdinit();                    //Initilize LCD
WebsiteLogo();
while(1)
{
WebsiteLogo();
//get numb1
key = get_key();
writecmd(0x01);            //clear display
WebsiteLogo();
writedata(key);            //Echo the key pressed to LCD
num1 = get_num(key);       //Get int number from char value, it checks for wrong input as well

if(num1!=Error)            //if correct input then proceed, num1==Error means wrong input
{
//get function
key = get_key();
writedata(key);                  //Echo the key pressed to LCD
func = get_func(key);            //it checks for wrong func

if(func!='e')                    //if correct input then proceed, func=='e' means wrong input
{
//get numb2
key = get_key();
writedata(key);              //Echo the key pressed to LCD
num2 = get_num(key);         //Get int number from char value, it checks for wrong input as well

if(num2!=Error)              //if correct input then proceed, num2==Error means wrong input
{
//get equal sign
key = get_key();
writedata(key);          //Echo the key pressed to LCD

if(key == '=')           //if = is pressed then proceed
{
switch(func)         //switch on function
{
case '+': disp_num(num1+num2); break;
case '-': disp_num(num1-num2); break;
case 'x': disp_num(num1*num2); break;
case '/': disp_num(num1/num2); break;
}
}
else				      //key other then = here means error wrong input
{
if(key == 'C')       //if clear screen is pressed then clear screen and reset
{
writecmd(0x01);   //Clear Screen
WebsiteLogo();
}
else
{
DispError(0); 	  //Display wrong input error
WebsiteLogo();
}
}
}
}
}
}
}

void WebsiteLogo()
{
writecmd(0x95);
writedata('w');                                 //write
writedata('w');                                 //write
writedata('w');                                 //write
writedata('.');                                 //write
writedata('T');                                 //write
writedata('h');                                 //write
writedata('e');                                 //write
writedata('E');                                 //write
writedata('n');                                 //write
writedata('g');                                 //write
writedata('i');                                 //write
writedata('n');                                 //write
writedata('e');                                 //write
writedata('e');                                 //write
writedata('r');                                 //write
writedata('i');                                 //write
writedata('n');                                 //write
writedata('g');                                 //write

writecmd(0xd8);

writedata('P');                                 //write
writedata('r');                                 //write
writedata('o');                                 //write
writedata('j');                                 //write
writedata('e');                                 //write
writedata('c');                                 //write
writedata('t');                                 //write
writedata('s');                                 //write
writedata('.');                                 //write
writedata('c');                                 //write
writedata('o');                                 //write
writedata('m');                                 //write
writecmd(0x80);
}

void cct_init(void)
{
P0 = 0x00;   //not used
P1 = 0xf0;   //used for generating outputs and taking inputs from Keypad
P2 = 0x00;   //used as data port for LCD
P3 = 0x00;   //used for RS and E
}

void delay(int a)
{
int i;
for(i=0;i<a;i++);   //null statement
}

void writedata(char t)
{
RS = 1;             // This is data
P2 = t;             //Data transfer
E  = 1;             // => E = 1
delay(150);
E  = 0;             // => E = 0
delay(150);
}

void writecmd(int z)
{
RS = 0;             // This is command
P2 = z;             //Data transfer
E  = 1;             // => E = 1
delay(150);
E  = 0;             // => E = 0
delay(150);
}

void lcdinit(void)
{
///////////// Reset process from datasheet /////////
delay(15000);
writecmd(0x30);
delay(4500);
writecmd(0x30);
delay(300);
writecmd(0x30);
delay(650);
/////////////////////////////////////////////////////
writecmd(0x38);    //function set
writecmd(0x01);    //clear display
writecmd(0x06);    //entry mode, set increment
}

{
writecmd(0x02);
delay(1500);
WebsiteLogo();
}

void writeline(char Line[])
{
int i;
for(i=0;i<strlen(Line);i++)
{
writedata(Line[i]);     /* Write Character */
}

}

{
RowA = 0; RowB = 1; RowC = 1; RowD = 1; 	//Test Row A

if (C1 == 0) { delay(10000); while (C1==0); return '7'; }
if (C2 == 0) { delay(10000); while (C2==0); return '8'; }
if (C3 == 0) { delay(10000); while (C3==0); return '9'; }
if (C4 == 0) { delay(10000); while (C4==0); return '/'; }

RowA = 1; RowB = 0; RowC = 1; RowD = 1; 	//Test Row B

if (C1 == 0) { delay(10000); while (C1==0); return '4'; }
if (C2 == 0) { delay(10000); while (C2==0); return '5'; }
if (C3 == 0) { delay(10000); while (C3==0); return '6'; }
if (C4 == 0) { delay(10000); while (C4==0); return 'x'; }

RowA = 1; RowB = 1; RowC = 0; RowD = 1; 	//Test Row C

if (C1 == 0) { delay(10000); while (C1==0); return '1'; }
if (C2 == 0) { delay(10000); while (C2==0); return '2'; }
if (C3 == 0) { delay(10000); while (C3==0); return '3'; }
if (C4 == 0) { delay(10000); while (C4==0); return '-'; }

RowA = 1; RowB = 1; RowC = 1; RowD = 0; 	//Test Row D

if (C1 == 0) { delay(10000); while (C1==0); return 'C'; }
if (C2 == 0) { delay(10000); while (C2==0); return '0'; }
if (C3 == 0) { delay(10000); while (C3==0); return '='; }
if (C4 == 0) { delay(10000); while (C4==0); return '+'; }

return 'n';           	// Means no key has been pressed
}

char get_key(void)           //get key from user
{
char key = 'n';              //assume no key pressed

while(key=='n')              //wait untill a key is pressed
key = READ_SWITCHES();   //scan the keys again and again

return key;                  //when key pressed then return its value
}

int get_num(char ch)         //convert char into int
{
switch(ch)
{
case '0': return 0; break;
case '1': return 1; break;
case '2': return 2; break;
case '3': return 3; break;
case '4': return 4; break;
case '5': return 5; break;
case '6': return 6; break;
case '7': return 7; break;
case '8': return 8; break;
case '9': return 9; break;
case 'C': writecmd(0x01); return Error; break;  //this is used as a clear screen and then reset by setting error
default: DispError(0); return Error; break;     //it means wrong input
}
}

char get_func(char chf)            //detects the errors in inputted function
{
if(chf=='C')                   //if clear screen then clear the LCD and reset
{
writecmd(0x01);            //clear display
WebsiteLogo();
return 'e';
}

if( chf!='+' && chf!='-' && chf!='x' && chf!='/' )  //if input is not from allowed funtions then show error
{
DispError(1);
WebsiteLogo();
return 'e';
}

return chf;                        //function is correct so return the correct function
}

void DispError(int numb)           //displays differet error messages
{
writecmd(0x01);                //clear display
WebsiteLogo();
switch(numb)
{
case 0: 	writeline("Wrong Input");      break;
case 1: 	writeline("Wrong Function");   break;
default:    writeline("Wrong Input");      break;
}
}

void disp_num(int numb)            //displays number on LCD
{
unsigned char UnitDigit  = 0;  //It will contain unit digit of numb
unsigned char TenthDigit = 0;  //It will contain 10th position digit of numb

if(numb<0)
{
numb = -1*numb;  // Make number positive
writedata('-');	 // Display a negative sign on LCD
}

TenthDigit = (numb/10);	          // Findout Tenth Digit

if( TenthDigit != 0)	          // If it is zero, then don't display
writedata(TenthDigit+0x30);	  // Make Char of TenthDigit and then display it on LCD

UnitDigit = numb - TenthDigit*10;

writedata(UnitDigit+0x30);	  // Make Char of UnitDigit and then display it on LCD
}

```
• The above code is quite self explanatory and the main part I have already explained but still if you get into any troubled then ask in comments and I will resolve them.
• Now copy this code in your keil uvision 3 and get the hex file.