# Looking help on calculator programming

Discussion in 'Microcontrollers' started by Parth86, Aug 2, 2017.

1. ### Parth86Member

Joined:
Dec 25, 2011
Messages:
515
Likes:
5
I want to write c program for calculator but I think at this time I don't have capabilities to writes c program for calculator. so for deep understanding I started with addition only .. I want to write c program that can do addition like below example
Example 1+2 =3, 2+1=3, 12+1=13, 1+12=13, 21+2=23, 21+1=22..... and so on

consider I have 8051 LCD and four switches to perform addition
Switch 1 = "1"
switch 2 = "+"
Switch 3 = "2"
Switch 4 = "="

if switch 1 is pressed than display number '1" on LCD.
if switch 2 is pressed than display operator "+" on LCD.
if switch 3 is pressed than display operator "2" on LCD.
if switch 4 is pressed than display"result" on LCD

basic steps
1) get the first argument, maybe one or digits
2) get the operator '+'
3) get the second argument maybe one or digits
4) get another operator '=' then perform the operation

Look at this program. This program display "1" when I press switch 1 and display "2" when I press switch 2

Code (c):

#include<reg51.h>
/* Data pins connected to port P1 of 8051 */
#define  Data_Port_Pins        (P1)
sbit    Register_Select_Pin   = P2^0;           /* Register Pin of LCD connected to Pin 0 of Port P2 */
sbit    Read_Write_Pin        = P2^1;           /* Read/Write Pin of LCD connected to Pin 1 of Port P2 */
sbit    Enable_Pin            = P2^2;           /* EN pin connected to pin 2 of port P2 */
sbit    Switch1               = P3^0;           /* switch 1 connected to port pin P3.0 */
sbit    Switch2               = P3^3;           /* switch 2 connected to port pin P3.3 */
sbit    Switch3               = P3^4;
sbit    Switch4               = P3^5;
/* Function for creating delay in milliseconds */
void Delay(unsigned int wait)
{
unsigned i, j;
for(i = 0; i < wait; i++)
for(j = 0; j < 1200; j++);
}
/* Function to send command instruction to LCD */
void LCD_Command (unsigned char cmd)
{
Data_Port_Pins = cmd;
Register_Select_Pin =0;
Enable_Pin =1;
Delay (2);
Enable_Pin =0;
}
/* Function to send display data to LCD */
void LCD_Data (unsigned char Data)
{
Data_Port_Pins = Data;
Register_Select_Pin=1;
Enable_Pin =1;
Delay(2);
Enable_Pin =0;
}
/* Function to prepare the LCD  and get it ready */
void LCD_Initialization()
{
LCD_Command(0x38);
Delay(20);
LCD_Command(0x0e);
Delay(20);
LCD_Command(0x06);
Delay(20);
LCD_Command(0x01);
Delay(20);
}
/* Function to send string to LCD */
void LCD_String (unsigned char *string)
{
int i=0;
while(string[i]!='\0')
{
LCD_Data(string[i]);
i++;
Delay(10);
}
return;
}
void main()
{
unsigned char string1[] ="1";
unsigned char string2[] ="2";
LCD_Initialization();
while(1)
{
if (Switch1 == 1)
{
LCD_Command(0x82);
LCD_String(string1);
Delay(500);
LCD_Command(0x01);
}
else if (Switch2 == 1)
{
LCD_Command(0x82);
LCD_String(string2);
Delay(500);
LCD_Command(0x01);
Delay(10);
}
else
{
LCD_Command(0x01);
}
}
}

Now how to write c program for addition ?
Note: I have replaced keypad with switch for easy understanding

Joined:
Mar 28, 2011
Messages:
9,163
Likes:
909
Location:
Rochdale UK
ONLINE
First... Map a keyboard so the result is 0~9 , +, -, / * and enter ( possibly a clear key ).

Then you need three arguments... Op1 Op2 and result..

Set up a 4 state scenario with

1 enter operand ( maybe a few key presses )
2 enter operator ( ends state 1 and stores operator )
3 enter second digits (again a few keypresses )
4 deduce and display. ( ends state 3 and works out answer. )

I have done this so when you struggle... I'll help

• Like x 1
3. ### Parth86Member

Joined:
Dec 25, 2011
Messages:
515
Likes:
5
I didn't want to use keypad because its so complicated for me. I have seen some program for keypad interfacing but really I don't understand the big program. My main aim is to learn programming with basics. so , I am trying to start with only four switch buttons. I am trying to write program for calculator which can do only addition. I don't have any idea how to complete program.

so I started to learn one by one. first I wrote program that display number on LCD. than I wrote program to display number if switch pressed. after that I wrote program for two switches. I checked that program. if Switch 1 pressed than number 1 will display and switch 2 pressed number 2 will display. after that I tried to write program for addition with four switches but I am stuck I don't have any idea to write program for addition. how to write program for addition.

Last edited: Aug 2, 2017
4. ### DaveNew Member

Joined:
Jan 12, 1997
Messages:
-
Likes:
0

Joined:
Mar 28, 2011
Messages:
9,163
Likes:
909
Location:
Rochdale UK
ONLINE

With four buttons, it won't be a very good calculator.

In C there ate many tools to convert decimals to strings and visa~versa...

C also has an extensive math library!

6. ### Parth86Member

Joined:
Dec 25, 2011
Messages:
515
Likes:
5
okk I try to understand the code for keypad interfacing with microcontroller. I am trying to divide program into small parts.

This code is for keypad scanning
Code (c):

/* scan keypress on first Row 7 8 9 */
RowA = 0;
RowB = 1;
RowC = 1;
RowD = 1;

if (Column1 == 0)     /* key "7" is pressed */
if (Column2 == 0)     /* key "8" is pressed */
if (Column3 == 0)     /* key "9" is pressed */
if (Column4 == 0)     /* key "/" is pressed */

/* scan keypress on second Row 4 5 6 x */
RowA = 1;
RowB = 0;
RowC = 1;
RowD = 1;

if (Column1 == 0)     /* key "4" is pressed */
if (Column2 == 0)     /* key "5" is pressed */
if (Column3 == 0)     /* key "6" is pressed */
if (Column4 == 0)     /* key "x" is pressed */

/*scan keypress on third Row 1 2 3 -  */
RowA = 1;
RowB = 1;
RowC = 0;
RowD = 1;

if (Column1 == 0)     /* key "1" is pressed */
if (Column2 == 0)     /* key "2" is pressed */
if (Column3 == 0)     /* key "3" is pressed */
if (Column4 == 0)     /* key "-" is pressed */

// scan keypress on fourth Row C 0 = + */
RowA = 1;
RowB = 1;
RowC = 1;
RowD = 0;

if (Column1 == 0)     /* key "C"  is  pressed */
if (Column2 == 0)     /* key "0" is   pressed */
if (Column3 == 0)     /* key "+" is pressed */
if (Column4 == 0)     /* key "=" is pressed * /
I’m assigning high to all column and Then i am assigning first row to zero and keeps remaining row as high. to check which key is pressed. Then i am assigning second row to zero , than third and fourth row to zero to check which key is pressed

How to complete whole program ?

Joined:
Mar 28, 2011
Messages:
9,163
Likes:
909
Location:
Rochdale UK
ONLINE

look at this..
Code (c):

unsigned char KEY_Table[] = {0x31, 0x32, 0x33, 0x46,
0x34, 0x35, 0x36, 0x45,
0x37, 0x38, 0x39, 0x44,
0x41, 0x30, 0x42, 0x43}; // keypad numbers

unsigned char getkey()      //
{
char row;
unsigned char key = 0;
for(row = 0;row<4;row++)   // Four rows
{
if(!COL1) key=1;     // Check
if(!COL2) key=2;     // each
if(!COL3) key=3;     // column
if(!COL4) key=4;
if(key)
{
delayMs(300);
return (row*4) + key;   // if a key was pressed
// mulply rows by 4 and add
}
return 0;
}

This will grab a keypress... Then using the table you get the right key ( mapped ).

8. ### Parth86Member

Joined:
Dec 25, 2011
Messages:
515
Likes:
5
I got this program. can you help me to understand this program. I want to understand working of each function one by one . I don't understand use of "void writeline(char[]); " in below program

Code (c):

#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);

//*******************
//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

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

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

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
return 'e';
}

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

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

void DispError(int numb)           //displays differet error messages
{
writecmd(0x01);                //clear display

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
}

Joined:
Mar 28, 2011
Messages:
9,163
Likes:
909
Location:
Rochdale UK
ONLINE
It's a function definition ( A bad one at that )

If you are going to pass pointers it would be like this..
void writeline(char* str);

Plus!! They are passing constants so I would worry if it works atall...
This is more appropriate...
void writeline(const char* str);

But!! From this you can still see the calculations and functions.... I prefer my way of reading the keypad.

My calculator has 24 buttons.... I'll dig it out and show you!!