• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Looking help on calculator programming

Status
Not open for further replies.

Parth86

Member
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

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;
    Read_Write_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;
    Read_Write_Pin=0;
    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
 

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
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
 

Parth86

Member
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
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:

Parth86

Member
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!
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
C:
keypad_read ()
/* 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 ?
 

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
Reading a complete keypad is very easy..

look at this..
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 mask = 0xEF;      // mask for row selection
 char row;
 unsigned char key = 0;
 for(row = 0;row<4;row++)   // Four rows
  {
  KEY_PORT = mask;
  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
   }        // add the column.
  mask<<=1;       // next row.
  }
 return 0;
 }
This will grab a keypress... Then using the table you get the right key ( mapped ).
 

Parth86

Member
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

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 READ_SWITCHES(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(0x0c);    //display on,cursor off,blink off
   writecmd(0x01);    //clear display
   writecmd(0x06);    //entry mode, set increment
}

void ReturnHome(void)     /* Return to 0 cursor location */
{
   writecmd(0x02);
   delay(1500);
}

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

char READ_SWITCHES(void)   
{   
   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
}
 

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
I don't understand use of "void writeline(char[]); " in below program
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!!
 
Status
Not open for further replies.

Latest threads

EE World Online Articles

Loading
Top